diff --git a/TOOLS/config/test/profile.env b/TOOLS/config/test/profile.env index 9dbdefa..87f0b70 100644 --- a/TOOLS/config/test/profile.env +++ b/TOOLS/config/test/profile.env @@ -3,7 +3,7 @@ NUBES_API_ENDPOINT="https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" TOKEN_FILE="secrets/test.token" # Version -VERSION="5.0.60" +VERSION="5.0.61" # Docs generation — ONLY from docs_gen// (never from docs/) DOCS_GEN_DIR="provider/docs_gen/test" diff --git a/TOOLS/scripts/02_generate_resources_and_docs_v2.sh b/TOOLS/scripts/02_generate_resources_and_docs_v2.sh index 963ebf9..006776b 100755 --- a/TOOLS/scripts/02_generate_resources_and_docs_v2.sh +++ b/TOOLS/scripts/02_generate_resources_and_docs_v2.sh @@ -103,6 +103,7 @@ ${ROOT_DIR}/TOOLS/bin/docs-generator \ -resources "$RESOURCES_YAML_DIR" \ -docs "$DOCS_DIR" \ -services "$SERVICES_LIST_PATH" \ + -version "${VERSION:-2.x}" \ -api-endpoint "$DOCS_API_ENDPOINT" echo "Resources and docs generated in template format." diff --git a/TOOLS/scripts/03_build_and_upload_provider.sh b/TOOLS/scripts/03_build_and_upload_provider.sh index 82fad73..760e278 100755 --- a/TOOLS/scripts/03_build_and_upload_provider.sh +++ b/TOOLS/scripts/03_build_and_upload_provider.sh @@ -175,6 +175,7 @@ cp -a "${ROOT_DIR}/provider/." "$TMP_PROVIDER_DIR/" mkdir -p "$TMP_PROVIDER_DIR/resources_yaml" find "$TMP_PROVIDER_DIR/resources_yaml" -maxdepth 1 -type f -name '*.yaml' -delete cp -a "${PROFILE_RESOURCES_YAML_DIR}"/*.yaml "$TMP_PROVIDER_DIR/resources_yaml/" +cp "${PROFILE_RESOURCES_YAML_DIR}"/embed.go "$TMP_PROVIDER_DIR/resources_yaml/" 2>/dev/null || true cp "$TIMEOUTS_SOURCE" "$TMP_PROVIDER_DIR/internal/provider/operation_timeouts.json" mkdir -p "$TMP_PROVIDER_DIR/internal/resources_gen" diff --git a/generated/dev/docs/.gitkeep b/generated/dev/docs/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/dev/docs/akhq.md b/generated/dev/docs/akhq.md deleted file mode 100644 index b160ca3..0000000 --- a/generated/dev/docs/akhq.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## MAN - -
-# Инструкция по развертыванию Apache Kafka через платформу

---
## 1. Общая информация
AKHQ — это веб-интерфейс для работы с кластерами Apache Kafka.
Позволяет просматривать топики, consumer group'ы, сообщения, ACL, схему безопасности, состояние брокеров и метаданные.
Поддерживает работу с несколькими кластерами Kafka одновременно, включая внутренние и внешние (TLS) подключения.

## Доступные операции
- **create** — Создание ресурса AKHQ
- **suspend** — Остановка ресурса
- **resume** — Возобновление работы ресурса
- **modify** — Модификация настроек
- **delete** — Удаление ресурса

---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса Kafka:

* **Кластер Kafka к которому нужно настроить подключение**
Для использования AKHQ необходимо предварительно развернуть сервис Kafka. Пример: `kafka-external`.

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество узлов для работы Akhq. Пример `2`

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `512`

* **Квота (millicore ) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `500`

* **Имя домена:**
Dns Имя по которому будет происходить обращение к сервису. Указать необходимо уникальное имя до . ( то есть если необходимо получить dns ui) Пример: `kafka-external`

---
## 4. Выходные параметры
После успешного развертывания ресурса Kafka платформа возвращает ряд параметров.
Ключевым из них является:

**connectionUrl**
Это полное доменное имя (FQDN), по которому будет доступен интерфейс AKHQ. После развёртывания подождите несколько минут — UI станет доступен по HTTPS, как только все сервисы полностью запустятся.

**Учетные данные**
Здесь представлены поля для ввода логина и пароля, с помощью которых вы сможете авторизоваться в сервисе.

---
## 5. Дополнительная информация
Учётные записи, созданные для работы с AKHQ, предоставляют доступ только для просмотра данных. Для управления Kafka, пожалуйста, используйте возможности личного кабинета.
--- -
diff --git a/generated/dev/docs/akhq_example.md b/generated/dev/docs/akhq_example.md deleted file mode 100644 index 259b48c..0000000 --- a/generated/dev/docs/akhq_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Copy-ready manifest (`akhq_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_akhq" "baza" { - resource_realm = "TODO" # Выбрать платформу из списка - domain = "TODO" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - kafka_uid = "TODO" # Выбрать кластер из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_memory = 512 # Пример: `1024` - resource_cpu = 500 # Пример: `1000` - resource_instances = 1 -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_akhq.baza.state_params["имя_ключа"] -nubes_akhq.baza.state_out["имя_ключа"] -nubes_akhq.baza.state_params_flat["имя_ключа"] -nubes_akhq.baza.state_out_flat["имя_ключа"] -nubes_akhq.baza.vault_secrets["имя_ключа"] -nubes_akhq.baza.vault_url -nubes_akhq.baza.vault_user_path -nubes_akhq.baza.vault_fields -``` diff --git a/generated/dev/docs/akhq_ops.md b/generated/dev/docs/akhq_ops.md deleted file mode 100644 index 9e4364f..0000000 --- a/generated/dev/docs/akhq_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](akhq_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](akhq_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/akhq_outputs.md b/generated/dev/docs/akhq_outputs.md deleted file mode 100644 index 22405f5..0000000 --- a/generated/dev/docs/akhq_outputs.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` - -### `vault_secrets` ключи - -- `vault_secrets["pass"]` -- `vault_secrets["user"]` - diff --git a/generated/dev/docs/akhq_params.md b/generated/dev/docs/akhq_params.md deleted file mode 100644 index b419cf6..0000000 --- a/generated/dev/docs/akhq_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Parameters - -- [Create params](akhq_params_create.md) -- [Modify params](akhq_params_modify.md) diff --git a/generated/dev/docs/akhq_params_create.md b/generated/dev/docs/akhq_params_create.md deleted file mode 100644 index 687ca12..0000000 --- a/generated/dev/docs/akhq_params_create.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
550resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
553domainstringЕсли будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
555kafka_uiduuidВыбрать кластер из спискаref_svc_id=116
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
551resource_memoryinteger512Пример: `1024`minvalue=512
552resource_cpuinteger500Пример: `1000`minvalue=500
554resource_instancesinteger1minvalue=1
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/akhq_params_modify.md b/generated/dev/docs/akhq_params_modify.md deleted file mode 100644 index 1ba2657..0000000 --- a/generated/dev/docs/akhq_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
565kafka_uiduuidВыбрать кластер из спискаref_svc_id=116
diff --git a/generated/dev/docs/dnsrecord.md b/generated/dev/docs/dnsrecord.md deleted file mode 100644 index 22f9734..0000000 --- a/generated/dev/docs/dnsrecord.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## MAN - -
-Необходима DNS зона, в которой будет создана DNS запись.
Выберите
* Зону в которой будет создана запись
* Тип записи
* Имя записи
* Значение записи -
diff --git a/generated/dev/docs/dnsrecord_example.md b/generated/dev/docs/dnsrecord_example.md deleted file mode 100644 index 7ba7cc8..0000000 --- a/generated/dev/docs/dnsrecord_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Copy-ready manifest (`dnsrecord_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_dnsrecord" "baza" { - zone_uid = "TODO" # UUID экземпляра услуги DNS-зоны - record_type = "A" # Тип DNS-записи - record_name = "TODO" # Имя записи. Имя зоны в конце проставляется автоматически - record_input = "TODO" # Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - record_ttl = 3600 # Time-to-Leave записи. Раз в какое время запись будет обновлена -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dnsrecord.baza.state_params["имя_ключа"] -nubes_dnsrecord.baza.state_out["имя_ключа"] -nubes_dnsrecord.baza.state_params_flat["имя_ключа"] -nubes_dnsrecord.baza.state_out_flat["имя_ключа"] -nubes_dnsrecord.baza.vault_secrets["имя_ключа"] -nubes_dnsrecord.baza.vault_url -nubes_dnsrecord.baza.vault_user_path -nubes_dnsrecord.baza.vault_fields -``` diff --git a/generated/dev/docs/dnsrecord_ops.md b/generated/dev/docs/dnsrecord_ops.md deleted file mode 100644 index 475844c..0000000 --- a/generated/dev/docs/dnsrecord_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dnsrecord_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](dnsrecord_params_modify.md) diff --git a/generated/dev/docs/dnsrecord_outputs.md b/generated/dev/docs/dnsrecord_outputs.md deleted file mode 100644 index 4d127c2..0000000 --- a/generated/dev/docs/dnsrecord_outputs.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dnsServers"]` -- `state_out_flat["record"]` - diff --git a/generated/dev/docs/dnsrecord_params.md b/generated/dev/docs/dnsrecord_params.md deleted file mode 100644 index 84701f9..0000000 --- a/generated/dev/docs/dnsrecord_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Parameters - -- [Create params](dnsrecord_params_create.md) -- [Modify params](dnsrecord_params_modify.md) diff --git a/generated/dev/docs/dnsrecord_params_create.md b/generated/dev/docs/dnsrecord_params_create.md deleted file mode 100644 index b3a67ca..0000000 --- a/generated/dev/docs/dnsrecord_params_create.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
75zone_uiduuidUUID экземпляра услуги DNS-зоныref_svc_id=110
76record_typestringТип DNS-записиvalue_list=A, AAAA, CNAME, MX, PTR, SOA, SRV, TXT, LUA, NS, SSHFP
77record_namestringИмя записи. Имя зоны в конце проставляется автоматическиunique_scope=parent
78record_inputstringЗначение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
450record_ttlinteger3600Time-to-Leave записи. Раз в какое время запись будет обновленаminvalue=30; maxvalue=604800
diff --git a/generated/dev/docs/dnsrecord_params_modify.md b/generated/dev/docs/dnsrecord_params_modify.md deleted file mode 100644 index d3cdbdb..0000000 --- a/generated/dev/docs/dnsrecord_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
256record_inputstringЗапись. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP
diff --git a/generated/dev/docs/dnszone.md b/generated/dev/docs/dnszone.md deleted file mode 100644 index f8249dd..0000000 --- a/generated/dev/docs/dnszone.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## MAN - -
-## ![image](https://img.icons8.com/?size=50&id=41400&format=png) Необходимо делегировать зону у регистратора на Авторитетные DNS (Сервера зон)

ns3.ngcloud.ru
``` bash
185.247.187.83
2a10:aa80:0:5::3
```

ns4.ngcloud.ru
``` bash
81.22.46.43
2a10:aa80:0:6::3
``` -
diff --git a/generated/dev/docs/dnszone_example.md b/generated/dev/docs/dnszone_example.md deleted file mode 100644 index 048e1e3..0000000 --- a/generated/dev/docs/dnszone_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Copy-ready manifest (`dnszone_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_dnszone" "baza" { - zone_email = "TODO" # Контактный e-mail - zone_name = "TODO" # Имя зоны - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - zone_kind = "NATIVE" # Тип зоны - zone_time_to_refresh = 86400 # Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов - zone_time_to_retry = 7200 # Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов - zone_time_to_expire = 3600000 # Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным - zone_time_to_live = 86400 # Время, в течение которого информация будет кешироваться другими DNS-серверами -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dnszone.baza.state_params["имя_ключа"] -nubes_dnszone.baza.state_out["имя_ключа"] -nubes_dnszone.baza.state_params_flat["имя_ключа"] -nubes_dnszone.baza.state_out_flat["имя_ключа"] -nubes_dnszone.baza.vault_secrets["имя_ключа"] -nubes_dnszone.baza.vault_url -nubes_dnszone.baza.vault_user_path -nubes_dnszone.baza.vault_fields -``` diff --git a/generated/dev/docs/dnszone_ops.md b/generated/dev/docs/dnszone_ops.md deleted file mode 100644 index e07344c..0000000 --- a/generated/dev/docs/dnszone_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dnszone_params_create.md) -- `delete` diff --git a/generated/dev/docs/dnszone_outputs.md b/generated/dev/docs/dnszone_outputs.md deleted file mode 100644 index 0c3556d..0000000 --- a/generated/dev/docs/dnszone_outputs.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dnsServers"]` -- `state_out_flat["dnsServers.ns1.nubes.ru"]` -- `state_out_flat["dnsServers.ns2.nubes.ru"]` -- `state_out_flat["zoneSerial"]` -- `state_out_flat["zoneSoaServer"]` - diff --git a/generated/dev/docs/dnszone_params.md b/generated/dev/docs/dnszone_params.md deleted file mode 100644 index 0f1f739..0000000 --- a/generated/dev/docs/dnszone_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Parameters - -- [Create params](dnszone_params_create.md) -- [Modify params](dnszone_params_modify.md) diff --git a/generated/dev/docs/dnszone_params_create.md b/generated/dev/docs/dnszone_params_create.md deleted file mode 100644 index 0690a8f..0000000 --- a/generated/dev/docs/dnszone_params_create.md +++ /dev/null @@ -1,31 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
66zone_emailstringКонтактный e-mail
67zone_namestringИмя зоныregex=^([a-z0-9-]+\.)+[a-z0-9-]+$
69zone_masters_for_slavestringИспользовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов
284resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
68zone_kindstringNATIVEТип зоныvalue_list=NATIVE, SLAVE
70zone_time_to_refreshstring86400Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов
71zone_time_to_retrystring7200Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов
72zone_time_to_expirestring3600000Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным
73zone_time_to_livestring86400Время, в течение которого информация будет кешироваться другими DNS-серверами
diff --git a/generated/dev/docs/dnszone_params_modify.md b/generated/dev/docs/dnszone_params_modify.md deleted file mode 100644 index bd1dc13..0000000 --- a/generated/dev/docs/dnszone_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/dummy.md b/generated/dev/docs/dummy.md deleted file mode 100644 index 53f9855..0000000 --- a/generated/dev/docs/dummy.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## MAN - -
-## Болванка для тестов.

А это просто много букв, чтобы посмотреть, как ведет себя текст при переполнении контейнера.


``` json
{
"iamServiceUrl": "https://auth-api-test.ngcloud.ru/api/v1/user",
"idpResponse": {
"prefix": {
"charset": "",
"status_text": "Request Time-out",
"text": true,
"errordetail": "",
"filecontent": "Connection Timeout",
"responseheader": {},
"header": "",
"statuscode": "408 Request Time-out",
"status_code": 408,
"mimetype": "Unable to determine MIME type of file."
}
}
}
``` -
diff --git a/generated/dev/docs/dummy_example.md b/generated/dev/docs/dummy_example.md deleted file mode 100644 index 4febf08..0000000 --- a/generated/dev/docs/dummy_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Copy-ready manifest (`dummy_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_dummy" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - duration_ms = 0 # перед завершением подождать (sleep) столько миллисекунд - fail_at_start = false # если true, завершить джоб, ничего не записывая в cmdb - fail_in_progress = false # если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - where_fail = 1 # принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dummy.baza.state_params["имя_ключа"] -nubes_dummy.baza.state_out["имя_ключа"] -nubes_dummy.baza.state_params_flat["имя_ключа"] -nubes_dummy.baza.state_out_flat["имя_ключа"] -nubes_dummy.baza.vault_secrets["имя_ключа"] -nubes_dummy.baza.vault_url -nubes_dummy.baza.vault_user_path -nubes_dummy.baza.vault_fields -``` diff --git a/generated/dev/docs/dummy_ops.md b/generated/dev/docs/dummy_ops.md deleted file mode 100644 index 3af1a55..0000000 --- a/generated/dev/docs/dummy_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dummy_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](dummy_params_modify.md) -- `reconcile` -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/dev/docs/dummy_outputs.md b/generated/dev/docs/dummy_outputs.md deleted file mode 100644 index 52b99e1..0000000 --- a/generated/dev/docs/dummy_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `vault_secrets` ключи - -- `vault_secrets["someKey"]` - diff --git a/generated/dev/docs/dummy_params.md b/generated/dev/docs/dummy_params.md deleted file mode 100644 index 67ae088..0000000 --- a/generated/dev/docs/dummy_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Parameters - -- [Create params](dummy_params_create.md) -- [Modify params](dummy_params_modify.md) diff --git a/generated/dev/docs/dummy_params_create.md b/generated/dev/docs/dummy_params_create.md deleted file mode 100644 index a098d0b..0000000 --- a/generated/dev/docs/dummy_params_create.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
242resource_realmstringНаименование ресурсной платформы для подключенияfunc=getAvailableResourceRealms
286bodymessagestringДата, уходящая в Vault
321map_examplemap
322json_examplejsonДля тестирования интерфейса. Сюда можно писать корректный json
396nested_ref_example
447yaml_exampleyaml
647map_fixedmap-fixedНовый тип поля
654array_map_fixed_examplearray-map-fixedArray of map-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
198duration_msinteger0перед завершением подождать (sleep) столько миллисекунд
199fail_at_startbooleanfalse**Операция не будет завершена**
Она будет в постоянном статусе PENDING, однако в Jenkins Job завершится с ошибкой
value_list=false, true
200fail_in_progressbooleanfalseесли true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdbvalue_list=false, true
201where_failinteger1принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault writevalue_list=1, 2, 3
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/dummy_params_modify.md b/generated/dev/docs/dummy_params_modify.md deleted file mode 100644 index b601221..0000000 --- a/generated/dev/docs/dummy_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
287duration_msintegerперед завершением подождать (sleep) столько миллисекунд
288fail_at_startbooleanесли true, завершить джоб, ничего не записывая в cmdbvalue_list=false, true
289fail_in_progressbooleanесли true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdbvalue_list=false, true
290where_failintegerпринимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault writevalue_list=1, 2, 3
291bodymessageДата, уходящая в Vault
373map_examplemap
374json_example
diff --git a/generated/dev/docs/flask.md b/generated/dev/docs/flask.md deleted file mode 100644 index 763135a..0000000 --- a/generated/dev/docs/flask.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## MAN - -
-# Инструкция по развертыванию Web-сервер с фреймворком Flask через платформу

## 1. Общая информация

Сервис **Web-сервер с фреймворком Flask** предназначен для развертывания веб-приложений на базе Flask.

### Доступные операции

create — включить сервис, развернуть веб-приложение с указанными параметрами.
delete — удалить сервис, только после suspend.
modify — изменить настройки сервиса и переразвернуть.
suspend — выключить веб-приложение, остановить обслуживание.
resume — включить веб-приложение после suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Имя домена
Описание: доменное имя для доступа к веб-приложению. Если указан FQDN, происходит проверка DNS на валидность А-записи. А-запись должна указывать на балансировщик ресурсной платформы. Если указано имя в рамках одного октета, оно будет добавлено в публичную DNS-зону.
Пример значения: строка, допустимые FQDN или имя в одном октете. Пример: example.com или myapp.

### Платформа для развертывания
Описание: кластер Kubernetes, в котором будет развернуто приложение.
Пример значения: идентификатор кластера Kubernetes.

### Квота ядра пода
Описание: количество CPU, выделяемое на под, в Milicores.
Пример значения: целое число, например 500 для 0.5 ядра.

### Квота памяти пода
Описание: количество памяти, выделяемое на под, в Megabytes.
Пример значения: целое число, например 512 для 512 MB.

### Кол-во реплик пода
Описание: количество инстансов пода для масштабирования.
Пример значения: целое число, шт, например 2.

### URL Проекта (gitpath)
Описание: полный HTTPS путь до проекта в Git-репозитории.
Пример значения: URL в формате https://github.com/myuser/myproject.git. Доступ к репозиторию должен быть публичным.

### URL HealthCheck
Описание: путь для проверки здоровья приложения внутри пода.
Пример значения: строка, путь, например /api/v1/health.

### Переменные окружения пода
Описание: структура данных, которая будет передана как переменные окружения в под.
Пример значения: ключ-значение, например {"ENV": "production"}.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Квота ядра пода: 300m (0.3 ядра)
- Квота памяти пода: 256 MB
- Кол-во реплик пода: 1

### Промышленное окружение
- Квота ядра пода: от 1000m (1 ядро) в зависимости от нагрузки
- Квота памяти пода: от 1024 MB (1 GB) с учетом потребностей приложения
- Кол-во реплик пода: от 2 для обеспечения отказоустойчивости

---

## 4. Выходные параметры
Операция create не возвращает явных выходных параметров. Успешное выполнение операции приводит к развертыванию сервиса, доступного по указанному домену.

---

## 5. Дополнительная информация
- В корне проекта должен находиться файл requirements.txt со списком зависимостей Python.
- Исходный код веб-приложения должен располагаться в директории site.
- Запуск веб-сервера осуществляется командой python app.py.
- Используется версия Python: python:3.12-slim.
- Git-репозиторий должен быть публично доступен для платформы.
- Операция delete возможна только после suspend.
- Операция modify приводит к переразвертыванию с новыми параметрами. -
diff --git a/generated/dev/docs/flask_example.md b/generated/dev/docs/flask_example.md deleted file mode 100644 index 80de273..0000000 --- a/generated/dev/docs/flask_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Copy-ready manifest (`flask_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_flask" "baza" { - resource_realm = "TODO" # Кластер Kubernetes в котором будет развёрнуто приложение - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан `FQDN`, то происходят проверки DNS на валидность А-записи. А-запись **обязана смотреть на балансировщик** ресурсной платформы. Если указано имя `в рамках одного октета`, будет добавлено **в публичную днс-зону** - resource_cpu = 300 # Пример: `1000` - resource_memory = 256 # Пример: `2048` - resource_instances = 1 # Пример: `3` - git_path = "https://github.com/Foxyhhd/Baldurs-Gate-test.git" # Пример: `https://github.com/myuser/myproject.git` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_flask.baza.state_params["имя_ключа"] -nubes_flask.baza.state_out["имя_ключа"] -nubes_flask.baza.state_params_flat["имя_ключа"] -nubes_flask.baza.state_out_flat["имя_ключа"] -nubes_flask.baza.vault_secrets["имя_ключа"] -nubes_flask.baza.vault_url -nubes_flask.baza.vault_user_path -nubes_flask.baza.vault_fields -``` diff --git a/generated/dev/docs/flask_ops.md b/generated/dev/docs/flask_ops.md deleted file mode 100644 index 518dea6..0000000 --- a/generated/dev/docs/flask_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](flask_params_create.md) -- `delete` — Удаление возможно только после остановки сервиса через операцию `suspend` После выполнения операции необходимо выждать определенное кол-во времени -- `modify` — Изменение кластера. Параметры: [Modify params](flask_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/flask_outputs.md b/generated/dev/docs/flask_outputs.md deleted file mode 100644 index 3c2d51a..0000000 --- a/generated/dev/docs/flask_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/flask_params.md b/generated/dev/docs/flask_params.md deleted file mode 100644 index ca3f639..0000000 --- a/generated/dev/docs/flask_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Parameters - -- [Create params](flask_params_create.md) -- [Modify params](flask_params_modify.md) diff --git a/generated/dev/docs/flask_params_create.md b/generated/dev/docs/flask_params_create.md deleted file mode 100644 index 8227804..0000000 --- a/generated/dev/docs/flask_params_create.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
249resource_realmstringВыбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы
func=getAvailableResourceRealms
254json_envmapСтруктура, которая будет передана как переменные окружения
255health_pathstringМожет быть пустым. Если ничего не передано, проверяется `tcpsocket`
Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
248domainstringweb01Если будет указан `FQDN`, то происходят проверки DNS на валидность А-записи. А-запись **обязана смотреть на балансировщик** ресурсной платформы.
Если указано имя `в рамках одного октета`, будет добавлено **в публичную днс-зону**
regex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
250resource_cpuinteger300Указывается в Milicores
`1000` Mili == `1` Ядро
minvalue=100; maxvalue=8000
251resource_memoryinteger256Указывается в Megabytesminvalue=128; maxvalue=8192
252resource_instancesinteger1Балансировка производится между всеми репликамиminvalue=1; maxvalue=7
253git_pathstringhttps://github.com/Foxyhhd/Baldurs-Gate-test.gitПроект должен быть публичным
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/flask_params_modify.md b/generated/dev/docs/flask_params_modify.md deleted file mode 100644 index 1f5f44b..0000000 --- a/generated/dev/docs/flask_params_modify.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Modify params - - - - - - - - - -
IDCodeTypeDescriptionConstraints
451resource_cpuintegerУказывается в Milicores
`1000` Mili == `1` Ядро
minvalue=100; maxvalue=8000
452resource_memoryintegerУказывается в Megabytesminvalue=128; maxvalue=8192
453resource_instancesintegerБалансировка производится между всеми репликамиminvalue=1; maxvalue=7
454git_pathПроект должен быть публичным
455json_envmapСтруктура, которая будет передана как переменные окружения
diff --git a/generated/dev/docs/gitea.md b/generated/dev/docs/gitea.md deleted file mode 100644 index b0fabf5..0000000 --- a/generated/dev/docs/gitea.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## MAN - -
-Развертывает сервис контроля версий Gitea
Зависит от сервиса postgresql который должен быть развернут заранее. -
diff --git a/generated/dev/docs/gitea_example.md b/generated/dev/docs/gitea_example.md deleted file mode 100644 index be105b4..0000000 --- a/generated/dev/docs/gitea_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Copy-ready manifest (`gitea_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_gitea" "baza" { - psql_uid = "TODO" # UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_gitea.baza.state_params["имя_ключа"] -nubes_gitea.baza.state_out["имя_ключа"] -nubes_gitea.baza.state_params_flat["имя_ключа"] -nubes_gitea.baza.state_out_flat["имя_ключа"] -nubes_gitea.baza.vault_secrets["имя_ключа"] -nubes_gitea.baza.vault_url -nubes_gitea.baza.vault_user_path -nubes_gitea.baza.vault_fields -``` diff --git a/generated/dev/docs/gitea_ops.md b/generated/dev/docs/gitea_ops.md deleted file mode 100644 index 0b22aac..0000000 --- a/generated/dev/docs/gitea_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](gitea_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](gitea_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/gitea_outputs.md b/generated/dev/docs/gitea_outputs.md deleted file mode 100644 index 3944814..0000000 --- a/generated/dev/docs/gitea_outputs.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` - diff --git a/generated/dev/docs/gitea_params.md b/generated/dev/docs/gitea_params.md deleted file mode 100644 index f0931ff..0000000 --- a/generated/dev/docs/gitea_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Parameters - -- [Create params](gitea_params_create.md) -- [Modify params](gitea_params_modify.md) diff --git a/generated/dev/docs/gitea_params_create.md b/generated/dev/docs/gitea_params_create.md deleted file mode 100644 index 378430a..0000000 --- a/generated/dev/docs/gitea_params_create.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
238psql_uiduuidUUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматическиref_svc_id=90
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
232resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=300; maxvalue=4000
233resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=256; maxvalue=8192
234resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
235resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
237domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/gitea_params_modify.md b/generated/dev/docs/gitea_params_modify.md deleted file mode 100644 index f584096..0000000 --- a/generated/dev/docs/gitea_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
259resource_cpuintegerКвота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=500; maxvalue=4000
260resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=256; maxvalue=8192
261resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
262resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
diff --git a/generated/dev/docs/harbor.md b/generated/dev/docs/harbor.md deleted file mode 100644 index c0cad0a..0000000 --- a/generated/dev/docs/harbor.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## MAN - -
-Расширенный реестр для управления Docker-образами с enterprise-функциями безопасности, репликации и контроля доступа.
Container Registry позволяет хранить, развертывать и управлять Docker-образами контейнеров в инфраструктуре NGcloud.
Сервис можно использовать в процессе разработки контейнеров. Например, вы можете настроить систему автоматизации на работу с реестром в Container Registry в рамках процесса непрерывной интеграции. Контейнеры идеально подходят для запуска небольших, независимых и легко изменяемых сервисов.
Чтобы начать работу, создайте реестр и загрузите в него Docker-образ
Авторизация: keycloak -
diff --git a/generated/dev/docs/harbor_example.md b/generated/dev/docs/harbor_example.md deleted file mode 100644 index af9351a..0000000 --- a/generated/dev/docs/harbor_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Copy-ready manifest (`harbor_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_harbor" "baza" { - resource_realm = "TODO" # Платформа для развертывания - s3_uid = "TODO" # UUID экземпляра услуги S3 - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - emails = "testuser1" # Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел - resource_cpu = 100 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 200 # Квота памяти пода (Указывается в Megabytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_harbor.baza.state_params["имя_ключа"] -nubes_harbor.baza.state_out["имя_ключа"] -nubes_harbor.baza.state_params_flat["имя_ключа"] -nubes_harbor.baza.state_out_flat["имя_ключа"] -nubes_harbor.baza.vault_secrets["имя_ключа"] -nubes_harbor.baza.vault_url -nubes_harbor.baza.vault_user_path -nubes_harbor.baza.vault_fields -``` diff --git a/generated/dev/docs/harbor_ops.md b/generated/dev/docs/harbor_ops.md deleted file mode 100644 index 9a06a19..0000000 --- a/generated/dev/docs/harbor_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](harbor_params_create.md) -- `delete` — DEV-Ветка удаления Harbor diff --git a/generated/dev/docs/harbor_outputs.md b/generated/dev/docs/harbor_outputs.md deleted file mode 100644 index 3422bbd..0000000 --- a/generated/dev/docs/harbor_outputs.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.k8sregistry"]` -- `state_out_flat["monitoring.k8sregistry.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` - diff --git a/generated/dev/docs/harbor_params.md b/generated/dev/docs/harbor_params.md deleted file mode 100644 index 6819254..0000000 --- a/generated/dev/docs/harbor_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Parameters - -- [Create params](harbor_params_create.md) -- [Modify params](harbor_params_modify.md) diff --git a/generated/dev/docs/harbor_params_create.md b/generated/dev/docs/harbor_params_create.md deleted file mode 100644 index d5f1c60..0000000 --- a/generated/dev/docs/harbor_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
110resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
231s3_uiduuidUUID экземпляра услуги S3ref_svc_id=12
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
16domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
17emailsstringtestuser1Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел
228resource_cpuinteger100Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
229resource_memoryinteger200Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
230resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
diff --git a/generated/dev/docs/harbor_params_modify.md b/generated/dev/docs/harbor_params_modify.md deleted file mode 100644 index 0960de7..0000000 --- a/generated/dev/docs/harbor_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/http.md b/generated/dev/docs/http.md deleted file mode 100644 index 68075b0..0000000 --- a/generated/dev/docs/http.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/dev/docs/http_example.md b/generated/dev/docs/http_example.md deleted file mode 100644 index 97655b7..0000000 --- a/generated/dev/docs/http_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Copy-ready manifest (`http_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_http" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 100 # Квота ядра пода (Указывается в mili) - resource_memory = 200 # Квота памяти пода (Указывается в Megabytes) - resource_instances = 1 # Количество узлов - registry_path = "nexus-sa.tst.nubes.ru/docker-nubes/jolt" # Путь до image, который будет установлен как deployment - json_env = {"param": "value"} # Массив переменных, будут переданы в env приложения -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_http.baza.state_params["имя_ключа"] -nubes_http.baza.state_out["имя_ключа"] -nubes_http.baza.state_params_flat["имя_ключа"] -nubes_http.baza.state_out_flat["имя_ключа"] -nubes_http.baza.vault_secrets["имя_ключа"] -nubes_http.baza.vault_url -nubes_http.baza.vault_user_path -nubes_http.baza.vault_fields -``` diff --git a/generated/dev/docs/http_ops.md b/generated/dev/docs/http_ops.md deleted file mode 100644 index 547defd..0000000 --- a/generated/dev/docs/http_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](http_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](http_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/dev/docs/http_outputs.md b/generated/dev/docs/http_outputs.md deleted file mode 100644 index 9baf737..0000000 --- a/generated/dev/docs/http_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/dev/docs/http_params.md b/generated/dev/docs/http_params.md deleted file mode 100644 index 07aa372..0000000 --- a/generated/dev/docs/http_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Parameters - -- [Create params](http_params_create.md) -- [Modify params](http_params_modify.md) diff --git a/generated/dev/docs/http_params_create.md b/generated/dev/docs/http_params_create.md deleted file mode 100644 index aa7d336..0000000 --- a/generated/dev/docs/http_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
216resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
212domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
213resource_cpuinteger100Квота ядра пода (Указывается в mili)minvalue=100; maxvalue=4000
214resource_memoryinteger200Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
215resource_instancesinteger1Количество реплик приложения. Трафик будет распределяться между подами в режиме Round-Robinminvalue=1; maxvalue=7
217registry_pathstringnexus-sa.tst.nubes.ru/docker-nubes/joltПуть до image, который будет установлен как deployment
241json_envjson{"param": "value"}Массив переменных, будут переданы в env приложения
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/http_params_modify.md b/generated/dev/docs/http_params_modify.md deleted file mode 100644 index 75a69ec..0000000 --- a/generated/dev/docs/http_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
218resource_cpuintegerminvalue=100; maxvalue=4000
219resource_memoryintegerminvalue=128; maxvalue=8192
220resource_instancesintegerКоличество узловminvalue=1; maxvalue=7
diff --git a/generated/dev/docs/index.md b/generated/dev/docs/index.md deleted file mode 100644 index 613a1ca..0000000 --- a/generated/dev/docs/index.md +++ /dev/null @@ -1,40 +0,0 @@ -# Ресурсы провайдера - -| ID | Ресурс | Описание | -|-----|--------|----------| -| 1 | [nubes_dummy](dummy.md) | Болванка | -| 2 | [nubes_template](template.md) | Темплейт k8s | -| 12 | [nubes_s3](s3.md) | S3 Object Storage | -| 13 | [nubes_s3bucket](s3bucket.md) | S3 бакет | -| 19 | [nubes_vc_org](vc_org.md) | Организация в Cloud Director | -| 21 | [nubes_vc_vdc](vc_vdc.md) | Виртуальный датацентр (vDC) | -| 22 | [nubes_vc_nsxt](vc_nsxt.md) | Сетевой шлюз периметра (Edge) | -| 25 | [nubes_vcexternalip](vcexternalip.md) | Публичные IP адреса | -| 26 | [nubes_vapp](vapp.md) | Виртуальный каталог ВМ (vApp) | -| 28 | [nubes_vc_vm_v3](vc_vm_v3.md) | Виртуальная машина | -| 29 | [nubes_vc_vdc_group](vc_vdc_group.md) | Группа датацентров | -| 50 | [nubes_nextcloud](nextcloud.md) | Nextcloud | -| 81 | [nubes_superset](superset.md) | Apache Superset | -| 82 | [nubes_harbor](harbor.md) | Container Registry | -| 88 | [nubes_k8s_ziti_controller](k8s_ziti_controller.md) | k8sZitiController | -| 89 | [nubes_flask](flask.md) | Web-сервер с фреймворком Flask | -| 90 | [nubes_postgres](postgres.md) | PostgreSQL | -| 91 | [nubes_redis](redis.md) | Redis | -| 92 | [nubes_mongodb](mongodb.md) | MongoDB | -| 93 | [nubes_rabbitmq](rabbitmq.md) | RabbitMQ | -| 94 | [nubes_lucee](lucee.md) | Lucee | -| 95 | [nubes_nodejs](nodejs.md) | NodeJS | -| 96 | [nubes_pgadmin](pgadmin.md) | pgAdmin | -| 97 | [nubes_nodered](nodered.md) | NodeRed | -| 98 | [nubes_http](http.md) | Простой HTTP контейнер | -| 99 | [nubes_gitea](gitea.md) | Gitea | -| 109 | [nubes_zones_v2](zones_v2.md) | Управление днс-зонами и записями | -| 110 | [nubes_dnszone](dnszone.md) | DNS зона | -| 111 | [nubes_dnsrecord](dnsrecord.md) | DNS запись | -| 115 | [nubes_mariadb](mariadb.md) | Mariadb | -| 116 | [nubes_kafka](kafka.md) | ApacheKafka | -| 119 | [nubes_akhq](akhq.md) | Akhq | -| 149 | [nubes_valo_tenant](valo_tenant.md) | VALO Cloud | -| 150 | [nubes_k8s_sthutrval_cluster](k8s_sthutrval_cluster.md) | Kubernetes кластер Штурвал | -| 151 | [nubes_k8s_openbao](k8s_openbao.md) | Vault | -| 153 | [nubes_nifi](nifi.md) | Nifi | diff --git a/generated/dev/docs/k8s_openbao.md b/generated/dev/docs/k8s_openbao.md deleted file mode 100644 index 98c440c..0000000 --- a/generated/dev/docs/k8s_openbao.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_k8s_openbao - -Service ID: `151` - -Service Name: Vault - -[Manual](k8s_openbao.md) | [Create params](k8s_openbao_params_create.md) | [Modify params](k8s_openbao_params_modify.md) | [Output params](k8s_openbao_outputs.md) | [Operations](k8s_openbao_ops.md) | [Example](k8s_openbao_example.md) - -## MAN - -
-# Инструкция по развертыванию Хранилища секретов через платформу

## 1. Общая информация
Хранилище секретов — сервис централизованного и защищённого хранения чувствительных данных (секретов, ключей, конфигураций). Предназначен для использования приложениями и сервисами в Kubernetes с управлением доступом на основе ролей.
В качестве приложения используется открытый проект OpenBao с поддержкой кластерного режима RAFT.

### Доступные операции
**create** — Создание хранилища секретов и инициализация кластера.
**delete** — Удаление хранилища секретов с полной очисткой всех связанных сущностей.
**modify** — Изменение параметров развернутого хранилища секретов.
**suspend** — Приостановка работы кластера без удаления Persistent Volume.
**resume** — Возобновление работы кластера с автоматическим unseal всех нод.
**restart** — Поочередный перезапуск нод с последующим подключением в кластер.
**create_kv** — Создание Key/Value хранилища версии V2.
**delete_kv** — Удаление Key/Value хранилища со всеми содержащимися секретами.
**create_secrets** — Создание секрета внутри Key/Value хранилища.
**delete_secrets** — Удаление секрета из Key/Value хранилища.
**update_secrets** — Обновление значения секрета.
**recovery_secrets** — Откат секрета к указанной версии.
**create_role** — Создание роли для управления Key/Value хранилищем или секретами.
**update_role** — Обновление параметров роли.
**delete_role** — Удаление роли доступа.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: Кластер Kubernetes, в котором будет развернуто приложение.
Формат значения: имя Kubernetes-кластера.

### Имя домена
Описание: Доменное имя сервиса. При указании полного FQDN выполняется проверка DNS A-записи или добавляется А-запись в техническую зону.
Формат значения: secrets.domain.com / mysecretdomain.

### Кол-во реплик
Описание: Количество узлов в кластере.
Формат значения: целое число.

### Квота ядра пода
Описание: Лимит CPU для одного узла. Указывается в milicores (1000 milicores = 1 CPU).
Формат значения: целое число.

### Квота памяти пода
Описание: Лимит оперативной памяти для одного узла. Указывается в megabytes.
Формат значения: целое число.

### Размер диска под хранение секретов
Описание: Объем диска для хранения данных. Фактический объем равен значению, умноженному на количество реплик. Указывается в Gigabytes
Формат значения: целое число.

### Версия OpenBao
Описание: Версия OpenBao для развертывания сервиса.
Формат значения: выбор из предоставленного списка версий.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
Кол-во реплик: 2.
Квота ядра пода: 200.
Квота памяти пода: 256.
Размер диска под хранение секретов: 1.
Версия OpenBao: актуальная стабильная версия.

### Промышленное окружение
Кол-во реплик: от 3.
Квота ядра пода: от 1000.
Квота памяти пода: от 1024.
Размер диска под хранение секретов: от 10.
Версия OpenBao: актуальная стабильная версия.

---

## 4. Выходные параметры
Настройки внутри хранилища (kv/secrets/roles) — конфигурации Key/Value, секретов и ролей, созданные соответствующими операциями.
Настройки самого хранилище (сайзинг, объемы) — параметры ресурсов и хранилища данных, примененные к сервису.
Статус кластера (running / suspended) — текущее состояние работы кластера.
url для подключения к веб — адрес веб-интерфейса сервиса.

---

## 5. Дополнительная информация
При удалении хранилища все данные и настройки безвозвратно удаляются.
При использовании доменного имени требуется корректная настройка DNS.
Операции управления секретами и ролями выполняются только после успешного создания хранилища.
Удаление кластера производится через операцию `suspend`, а удаление становится доступно через 14 дней после остановки кластера
Правило выше не относится к операции `delete_kv` / `delete_secrets` / `delete_role` -
diff --git a/generated/dev/docs/k8s_openbao_example.md b/generated/dev/docs/k8s_openbao_example.md deleted file mode 100644 index e62aa3a..0000000 --- a/generated/dev/docs/k8s_openbao_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_k8s_openbao - -Service ID: `151` - -Service Name: Vault - -[Manual](k8s_openbao.md) | [Create params](k8s_openbao_params_create.md) | [Modify params](k8s_openbao_params_modify.md) | [Output params](k8s_openbao_outputs.md) | [Operations](k8s_openbao_ops.md) | [Example](k8s_openbao_example.md) - -## Copy-ready manifest (`k8s_openbao_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_k8s_openbao" "baza" { - resource_realm = "TODO" # Кластер Kubernetes в котором будет развёрнуто приложение - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Пример: `500` - resource_instances = 3 # Пример: `3` - resource_memory = 512 # Пример: `2048` - resource_disk = 10 # Пример: `10` - app_version = 2.4.4 # Выбрать из списка - domain = "bao-" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_k8s_openbao.baza.state_params["имя_ключа"] -nubes_k8s_openbao.baza.state_out["имя_ключа"] -nubes_k8s_openbao.baza.state_params_flat["имя_ключа"] -nubes_k8s_openbao.baza.state_out_flat["имя_ключа"] -nubes_k8s_openbao.baza.vault_secrets["имя_ключа"] -nubes_k8s_openbao.baza.vault_url -nubes_k8s_openbao.baza.vault_user_path -nubes_k8s_openbao.baza.vault_fields -``` diff --git a/generated/dev/docs/k8s_openbao_ops.md b/generated/dev/docs/k8s_openbao_ops.md deleted file mode 100644 index e59e9c1..0000000 --- a/generated/dev/docs/k8s_openbao_ops.md +++ /dev/null @@ -1,26 +0,0 @@ -# Resource nubes_k8s_openbao - -Service ID: `151` - -Service Name: Vault - -[Manual](k8s_openbao.md) | [Create params](k8s_openbao_params_create.md) | [Modify params](k8s_openbao_params_modify.md) | [Output params](k8s_openbao_outputs.md) | [Operations](k8s_openbao_ops.md) | [Example](k8s_openbao_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](k8s_openbao_params_create.md) -- `create_kv` — Создание кластера. Параметры: [Create params](k8s_openbao_params_create.md) -- `create_policy` — Создание кластера. Параметры: [Create params](k8s_openbao_params_create.md) -- `create_secrets` — Создание кластера. Параметры: [Create params](k8s_openbao_params_create.md) -- `delete` -- `delete_kv` — **ОСТОРОЖНО** Удаление KV подразумевает удаление ВСЕХ secrets внутри этой KV -- `delete_policy` -- `delete_secrets` -- `modify` — Изменение кластера. Параметры: [Modify params](k8s_openbao_params_modify.md) -- `reconcile` -- `recovery_secrets` — Данная операция подразумевает откат на конкретную версию в секрете. **Это не восстановление удалённого секрета** -- `restart` -- `resume` -- `suspend` -- `update_policy` -- `update_secrets` diff --git a/generated/dev/docs/k8s_openbao_outputs.md b/generated/dev/docs/k8s_openbao_outputs.md deleted file mode 100644 index 5d750bd..0000000 --- a/generated/dev/docs/k8s_openbao_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_k8s_openbao - -Service ID: `151` - -Service Name: Vault - -[Manual](k8s_openbao.md) | [Create params](k8s_openbao_params_create.md) | [Modify params](k8s_openbao_params_modify.md) | [Output params](k8s_openbao_outputs.md) | [Operations](k8s_openbao_ops.md) | [Example](k8s_openbao_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/k8s_openbao_params.md b/generated/dev/docs/k8s_openbao_params.md deleted file mode 100644 index f87adc9..0000000 --- a/generated/dev/docs/k8s_openbao_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_openbao - -Service ID: `151` - -Service Name: Vault - -[Manual](k8s_openbao.md) | [Create params](k8s_openbao_params_create.md) | [Modify params](k8s_openbao_params_modify.md) | [Output params](k8s_openbao_outputs.md) | [Operations](k8s_openbao_ops.md) | [Example](k8s_openbao_example.md) - -## Parameters - -- [Create params](k8s_openbao_params_create.md) -- [Modify params](k8s_openbao_params_modify.md) diff --git a/generated/dev/docs/k8s_openbao_params_create.md b/generated/dev/docs/k8s_openbao_params_create.md deleted file mode 100644 index 984f213..0000000 --- a/generated/dev/docs/k8s_openbao_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_k8s_openbao - -Service ID: `151` - -Service Name: Vault - -[Manual](k8s_openbao.md) | [Create params](k8s_openbao_params_create.md) | [Modify params](k8s_openbao_params_modify.md) | [Output params](k8s_openbao_outputs.md) | [Operations](k8s_openbao_ops.md) | [Example](k8s_openbao_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
663resource_realmstringВыбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы
func=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
664resource_cpuinteger500Указывается в Milicores
`1000` Mili == `1` Ядро
minvalue=250; maxvalue=8000
665resource_instancesinteger3Пример: `3`minvalue=1; maxvalue=7
666resource_memoryinteger512Указывается в Megabytesminvalue=256; maxvalue=8192
667resource_diskinteger10Указывается в Gigabytesminvalue=1; maxvalue=999
668app_versionstring2.4.4Выбрать из спискаvalue_list=2.4.4
669domainstringbao-Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/k8s_openbao_params_modify.md b/generated/dev/docs/k8s_openbao_params_modify.md deleted file mode 100644 index cf43f39..0000000 --- a/generated/dev/docs/k8s_openbao_params_modify.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_k8s_openbao - -Service ID: `151` - -Service Name: Vault - -[Manual](k8s_openbao.md) | [Create params](k8s_openbao_params_create.md) | [Modify params](k8s_openbao_params_modify.md) | [Output params](k8s_openbao_outputs.md) | [Operations](k8s_openbao_ops.md) | [Example](k8s_openbao_example.md) - -## Modify params - - - - - - - - - -
IDCodeTypeDescriptionConstraints
670resource_instancesintegerПример: `3`minvalue=1; maxvalue=7
671resource_cpuintegerУказывается в Milicores
`1000` Mili == `1` Ядро
minvalue=250; maxvalue=8000
672resource_memoryintegerУказывается в Megabytesminvalue=256; maxvalue=8192
673resource_diskintegerУказывается в Gigabytesminvalue=1; maxvalue=999
674app_versionstringВыбрать из спискаvalue_list=2.4.4
diff --git a/generated/dev/docs/k8s_sthutrval_cluster.md b/generated/dev/docs/k8s_sthutrval_cluster.md deleted file mode 100644 index b3b0523..0000000 --- a/generated/dev/docs/k8s_sthutrval_cluster.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## MAN - -
-Перед разворачиванием убедиться, что в облаке есть 2 свободных невыделенных IP в пуле -
diff --git a/generated/dev/docs/k8s_sthutrval_cluster_example.md b/generated/dev/docs/k8s_sthutrval_cluster_example.md deleted file mode 100644 index fb256b8..0000000 --- a/generated/dev/docs/k8s_sthutrval_cluster_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Copy-ready manifest (`k8s_sthutrval_cluster_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_k8s_sthutrval_cluster" "baza" { - startup_configuration = "TODO" - control_plane_configuration = "TODO" - access_configuration = "TODO" - cluster_configuration = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - worker_configuration = [{}] -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_k8s_sthutrval_cluster.baza.state_params["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_out["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_params_flat["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_out_flat["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.vault_secrets["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.vault_url -nubes_k8s_sthutrval_cluster.baza.vault_user_path -nubes_k8s_sthutrval_cluster.baza.vault_fields -``` diff --git a/generated/dev/docs/k8s_sthutrval_cluster_ops.md b/generated/dev/docs/k8s_sthutrval_cluster_ops.md deleted file mode 100644 index afb94fd..0000000 --- a/generated/dev/docs/k8s_sthutrval_cluster_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](k8s_sthutrval_cluster_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](k8s_sthutrval_cluster_params_modify.md) -- `reconcile` -- `resume` -- `suspend` -- `update_secrets` diff --git a/generated/dev/docs/k8s_sthutrval_cluster_outputs.md b/generated/dev/docs/k8s_sthutrval_cluster_outputs.md deleted file mode 100644 index 065be3b..0000000 --- a/generated/dev/docs/k8s_sthutrval_cluster_outputs.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["ingressAddress"]` -- `state_out_flat["kubernetesApiAddress"]` - -### `vault_secrets` ключи - -- `vault_secrets["kubernetesAdminConfigB64"]` - diff --git a/generated/dev/docs/k8s_sthutrval_cluster_params.md b/generated/dev/docs/k8s_sthutrval_cluster_params.md deleted file mode 100644 index 641f838..0000000 --- a/generated/dev/docs/k8s_sthutrval_cluster_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Parameters - -- [Create params](k8s_sthutrval_cluster_params_create.md) -- [Modify params](k8s_sthutrval_cluster_params_modify.md) diff --git a/generated/dev/docs/k8s_sthutrval_cluster_params_create.md b/generated/dev/docs/k8s_sthutrval_cluster_params_create.md deleted file mode 100644 index 4ecc132..0000000 --- a/generated/dev/docs/k8s_sthutrval_cluster_params_create.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
750startup_configurationmap-fixed
751control_plane_configurationmap-fixed
753access_configurationmap-fixed
755cluster_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
752worker_configurationarray-map-fixed[{}]
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/k8s_sthutrval_cluster_params_modify.md b/generated/dev/docs/k8s_sthutrval_cluster_params_modify.md deleted file mode 100644 index f2f26fb..0000000 --- a/generated/dev/docs/k8s_sthutrval_cluster_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
756cluster_configurationmap-fixed
757control_plane_configurationmap-fixed
758worker_configurationarray-map-fixed
759access_configurationmap-fixed
diff --git a/generated/dev/docs/k8s_ziti_controller.md b/generated/dev/docs/k8s_ziti_controller.md deleted file mode 100644 index 5c8b8f3..0000000 --- a/generated/dev/docs/k8s_ziti_controller.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/dev/docs/k8s_ziti_controller_example.md b/generated/dev/docs/k8s_ziti_controller_example.md deleted file mode 100644 index bb586b6..0000000 --- a/generated/dev/docs/k8s_ziti_controller_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Copy-ready manifest (`k8s_ziti_controller_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_k8s_ziti_controller" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 300 # Квота ядра пода (milicores) - resource_memory = 512 # Квота памяти пода (MBytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_k8s_ziti_controller.baza.state_params["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_out["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_params_flat["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_out_flat["имя_ключа"] -nubes_k8s_ziti_controller.baza.vault_secrets["имя_ключа"] -nubes_k8s_ziti_controller.baza.vault_url -nubes_k8s_ziti_controller.baza.vault_user_path -nubes_k8s_ziti_controller.baza.vault_fields -``` diff --git a/generated/dev/docs/k8s_ziti_controller_ops.md b/generated/dev/docs/k8s_ziti_controller_ops.md deleted file mode 100644 index 8da7234..0000000 --- a/generated/dev/docs/k8s_ziti_controller_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](k8s_ziti_controller_params_create.md) -- `delete` diff --git a/generated/dev/docs/k8s_ziti_controller_outputs.md b/generated/dev/docs/k8s_ziti_controller_outputs.md deleted file mode 100644 index 6fc1fdd..0000000 --- a/generated/dev/docs/k8s_ziti_controller_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/k8s_ziti_controller_params.md b/generated/dev/docs/k8s_ziti_controller_params.md deleted file mode 100644 index 343d93e..0000000 --- a/generated/dev/docs/k8s_ziti_controller_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Parameters - -- [Create params](k8s_ziti_controller_params_create.md) -- [Modify params](k8s_ziti_controller_params_modify.md) diff --git a/generated/dev/docs/k8s_ziti_controller_params_create.md b/generated/dev/docs/k8s_ziti_controller_params_create.md deleted file mode 100644 index dac54da..0000000 --- a/generated/dev/docs/k8s_ziti_controller_params_create.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
298resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
294resource_cpuinteger300Квота ядра пода (milicores)minvalue=100; maxvalue=4000
295resource_memoryinteger512Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
296resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
297resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
299domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
diff --git a/generated/dev/docs/k8s_ziti_controller_params_modify.md b/generated/dev/docs/k8s_ziti_controller_params_modify.md deleted file mode 100644 index 1998e6a..0000000 --- a/generated/dev/docs/k8s_ziti_controller_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/kafka.md b/generated/dev/docs/kafka.md deleted file mode 100644 index 34f2d04..0000000 --- a/generated/dev/docs/kafka.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## MAN - -
-# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Идентификатор организации
Уникальный идентификатор созданной организации. Используется для всех дальнейших API-операций.

### Статус организации
Отражает текущее состояние: active, suspended, modifying, deleting.

### Параметры сети
Выходные данные при наличии ipSpaces: список выделенных внешних IP, имя ip_space, количество IP.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)**;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к этой организации.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak.

-
diff --git a/generated/dev/docs/kafka_example.md b/generated/dev/docs/kafka_example.md deleted file mode 100644 index 77ed3dc..0000000 --- a/generated/dev/docs/kafka_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Copy-ready manifest (`kafka_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_kafka" "baza" { - resource_instances = 1 # Пример: `2` - resource_memory = 1 # Пример: `2048` - resource_cpu = 1 # Пример: `2000` - resource_disk = 1 # Пример: `20` - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - need_external_address_master = false # Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_kafka.baza.state_params["имя_ключа"] -nubes_kafka.baza.state_out["имя_ключа"] -nubes_kafka.baza.state_params_flat["имя_ключа"] -nubes_kafka.baza.state_out_flat["имя_ключа"] -nubes_kafka.baza.vault_secrets["имя_ключа"] -nubes_kafka.baza.vault_url -nubes_kafka.baza.vault_user_path -nubes_kafka.baza.vault_fields -``` diff --git a/generated/dev/docs/kafka_ops.md b/generated/dev/docs/kafka_ops.md deleted file mode 100644 index 21e6e30..0000000 --- a/generated/dev/docs/kafka_ops.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](kafka_params_create.md) -- `create_topic` — Создание кластера. Параметры: [Create params](kafka_params_create.md) -- `create_user` — Создание кластера. Параметры: [Create params](kafka_params_create.md) -- `delete` -- `delete_topic` -- `delete_user` — # Инструкция по управлению пользователями Apache Kafka. --- ## 1. Общая информация Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру. Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам. Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka. --- ## Доступные операции - **create_user** — Создание пользователя - **modify_user** — Модификация пользователя - **delete_user** — Удаление пользователя --- ## 2. Параметры создания пользователя Ниже перечислены параметры, которые необходимо указать при создании нового пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 3. Параметры модификации пользователя Ниже перечислены параметры, которые необходимо указать при модификации пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 4. Параметры удалении пользователя Ниже перечислены параметры, которые необходимо указать при удалении пользователя: * **Имя пользователя** Имя удаляемого пользователя. Пример: `username-admin` ## 5. Выходные параметры После успешного создания пользователя платформа возвращает параметры, необходимые для подключения: * **ca.crt** Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении. Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **ca.p12** PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.p12 ``` * **ca.password** Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно. * **user.crt** Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka. Используется совместно с приватным ключом `user.key` для аутентификации. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **user.key** Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.key ``` * **user.p12** PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo "<содержание поля>" | base64 -d > <название>.p12 ``` * **user.password** Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно. Эти параметры используются для настройки TLS-подключения. --- ## 6. Пример конфигурации клиента внутри кластера Пример пода: ```yaml apiVersion: v1 kind: Pod metadata: name: kafka-4 spec: volumes: - name: work emptyDir: {} containers: - name: kcat image: quay.io/strimzi/kafka:latest-kafka-4.0.0 command: ["sleep", "5600"] volumeMounts: - name: work mountPath: /work restartPolicy: Never ``` Создаём под и сохраняем сертификаты: ```bash kubectl cp user.p12 kafka-4:/work/ kubectl cp ca.p12 kafka-4:/work/ ``` Создаём файлы конфигурации: ```bash cat > /work/user-read.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` ```bash cat > /work/user-write.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user-write.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` Листинг доступных топиков: ```bash /opt/kafka/bin/kafka-topics.sh \ --bootstrap-server kafkak8s-bootstrap-external:9093 \ --command-config /work/user-read.properties \ --list ``` Запись сообщений: ```bash /opt/kafka/bin/kafka-console-producer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --producer.config /work/user-write.properties ``` Чтение сообщений: ```bash /opt/kafka/bin/kafka-console-consumer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --from-beginning \ --group \ --consumer.config /work/user-read.properties \ --max-messages 50 ``` --- ## 7. Пример внешнего подключения с использованием **kcat** **Листинг топиков** ```bash kcat -b :9093 \ -L \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` **Запись сообщения** ```bash echo "hello from kcat" | kcat -P \ -b :9093 \ -t write-test \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-write.crt \ -X ssl.key.location=./user-write.key \ -X ssl.endpoint.identification.algorithm=none ``` **Чтение сообщений** ```bash kcat -C \ -b :9093 \ -t write-test \ -o beginning \ -q \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` --- ## 9. Рекомендации * Минимизируйте набор разрешённых операций для повышения безопасности. * Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов. * Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**. * После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам. --- -- `modify` — Изменение кластера. Параметры: [Modify params](kafka_params_modify.md) -- `modify_topic` — Изменение кластера. Параметры: [Modify params](kafka_params_modify.md) -- `modify_user` — Изменение кластера. Параметры: [Modify params](kafka_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/kafka_outputs.md b/generated/dev/docs/kafka_outputs.md deleted file mode 100644 index 7a36056..0000000 --- a/generated/dev/docs/kafka_outputs.md +++ /dev/null @@ -1,54 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.bootstrap"]` -- `state_out_flat["externalConnect.bootstrap.fqdn"]` -- `state_out_flat["externalConnect.bootstrap.ip"]` -- `state_out_flat["externalConnect.bootstrap.isExternal"]` -- `state_out_flat["externalConnect.bootstrap.uuid"]` -- `state_out_flat["internalConnect"]` -- `state_out_flat["kafkaTopics"]` -- `state_out_flat["kafkaTopics.test-events"]` -- `state_out_flat["kafkaTopics.test-events.partitions"]` -- `state_out_flat["kafkaTopics.test-events.replicas"]` -- `state_out_flat["kafkaUsers"]` -- `state_out_flat["kafkaUsers.usertest"]` -- `state_out_flat["kafkaUsers.usertest.accessHosts"]` -- `state_out_flat["kafkaUsers.usertest.group"]` -- `state_out_flat["kafkaUsers.usertest.nameTopic"]` -- `state_out_flat["kafkaUsers.usertest.operations"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["users"]` - diff --git a/generated/dev/docs/kafka_params.md b/generated/dev/docs/kafka_params.md deleted file mode 100644 index 25cb573..0000000 --- a/generated/dev/docs/kafka_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Parameters - -- [Create params](kafka_params_create.md) -- [Modify params](kafka_params_modify.md) diff --git a/generated/dev/docs/kafka_params_create.md b/generated/dev/docs/kafka_params_create.md deleted file mode 100644 index 1a43a4e..0000000 --- a/generated/dev/docs/kafka_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
461resource_instancesintegerПример: `2`minvalue=1; value_list=1, 2, 3, 4, 5
462resource_memoryintegerПример: `2048`minvalue=1000
463resource_cpuintegerПример: `2000`minvalue=1000
464resource_diskintegerПример: `20`
466ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
469resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
465need_external_address_masterbooleanfalseФлаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`value_list=false, true
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/kafka_params_modify.md b/generated/dev/docs/kafka_params_modify.md deleted file mode 100644 index e6ff431..0000000 --- a/generated/dev/docs/kafka_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
501resource_instancesintegerПример: `2`value_list=1, 2, 3, 4, 5
502resource_memoryintegerПример: `2048`minvalue=1000
503resource_cpuПример: `2000`minvalue=1000
504resource_diskintegerПример: `20`
505need_external_address_masterbooleanФлаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`value_list=false, true
506ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
diff --git a/generated/dev/docs/lucee.md b/generated/dev/docs/lucee.md deleted file mode 100644 index ca3542d..0000000 --- a/generated/dev/docs/lucee.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/dev/docs/lucee_example.md b/generated/dev/docs/lucee_example.md deleted file mode 100644 index 82b4927..0000000 --- a/generated/dev/docs/lucee_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Copy-ready manifest (`lucee_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_lucee" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "lucee-" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - git_path = "https://github.com/xahys/testlucee" # Путь до Git, который будет webroot для сайта - json_env = { "param": "value" } # Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения. - resource_cpu = 300 # Квота ядра пода (milicores) - resource_memory = 512 # Квота памяти пода (MBytes) - resource_instances = 1 # Количество узлов - app_version = 5.4 # Версия Lucee -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_lucee.baza.state_params["имя_ключа"] -nubes_lucee.baza.state_out["имя_ключа"] -nubes_lucee.baza.state_params_flat["имя_ключа"] -nubes_lucee.baza.state_out_flat["имя_ключа"] -nubes_lucee.baza.vault_secrets["имя_ключа"] -nubes_lucee.baza.vault_url -nubes_lucee.baza.vault_user_path -nubes_lucee.baza.vault_fields -``` diff --git a/generated/dev/docs/lucee_ops.md b/generated/dev/docs/lucee_ops.md deleted file mode 100644 index 3294ee8..0000000 --- a/generated/dev/docs/lucee_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](lucee_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](lucee_params_modify.md) -- `redeploy` -- `restart` -- `resume` -- `suspend` diff --git a/generated/dev/docs/lucee_outputs.md b/generated/dev/docs/lucee_outputs.md deleted file mode 100644 index 838f21d..0000000 --- a/generated/dev/docs/lucee_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/dev/docs/lucee_params.md b/generated/dev/docs/lucee_params.md deleted file mode 100644 index 730e3b2..0000000 --- a/generated/dev/docs/lucee_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Parameters - -- [Create params](lucee_params_create.md) -- [Modify params](lucee_params_modify.md) diff --git a/generated/dev/docs/lucee_params_create.md b/generated/dev/docs/lucee_params_create.md deleted file mode 100644 index 84476c6..0000000 --- a/generated/dev/docs/lucee_params_create.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
108resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
132health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
103domainstringlucee-Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
104git_pathstringhttps://github.com/xahys/testluceeПуть до Git, который будет webroot для сайта
105json_envjson{ "param": "value" }Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения.maxlength=2048
106resource_cpuinteger300Квота ядра пода (milicores)minvalue=100; maxvalue=4000
107resource_memoryinteger512Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
139resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
263app_versionstring5.4Версия Luceeregex=^\d+(\.\d+){1,2}(-[a-zA-Z0-9\.]+)?$; value_list=5.4, 6.0
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/lucee_params_modify.md b/generated/dev/docs/lucee_params_modify.md deleted file mode 100644 index 087ab68..0000000 --- a/generated/dev/docs/lucee_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
133git_pathstringПуть до Git, который будет webroot для сайта
134health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код.
135json_envjsonМассив переменных, будут переданы в env приложенияmaxlength=2048
136resource_cpuintegerКвота ядра пода (Указывается в mili)minvalue=100; maxvalue=4000
137resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
138resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
264app_versionstringregex=^\d+(\.\d+){1,2}(-[a-zA-Z0-9\.]+)?$; value_list=5.4, 6.0
diff --git a/generated/dev/docs/mariadb.md b/generated/dev/docs/mariadb.md deleted file mode 100644 index 9161094..0000000 --- a/generated/dev/docs/mariadb.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## MAN - -
-Mariadb кластер. Ресурсная платформа: k8s. Автоматизация: k8s operator.
Автоматическое резервное копирование, ручное восстановление. -
diff --git a/generated/dev/docs/mariadb_example.md b/generated/dev/docs/mariadb_example.md deleted file mode 100644 index a684bab..0000000 --- a/generated/dev/docs/mariadb_example.md +++ /dev/null @@ -1,57 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Copy-ready manifest (`mariadb_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_mariadb" "baza" { - resource_realm = "TODO" # Платформа для развертывания - s3_uid = "TODO" # Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Квота ядра пода (milicores) - resource_memory = 1024 # Квота памяти пода (MBytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - need_external_address_master = false # Выделяет внешний (белый) IP для доступа к master - ext_backup_schedule = "0 * * * *" # Не обязательный. Время запуска бекапа - app_version = 9.4.0 # Версия MySQL - auto_scale = false # Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги - auto_scale_percentage = 10 # Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема - auto_scale_tech_window = 0 # Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) - auto_scale_quota_gb = 1 # Квота для autoScale -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_mariadb.baza.state_params["имя_ключа"] -nubes_mariadb.baza.state_out["имя_ключа"] -nubes_mariadb.baza.state_params_flat["имя_ключа"] -nubes_mariadb.baza.state_out_flat["имя_ключа"] -nubes_mariadb.baza.vault_secrets["имя_ключа"] -nubes_mariadb.baza.vault_url -nubes_mariadb.baza.vault_user_path -nubes_mariadb.baza.vault_fields -``` diff --git a/generated/dev/docs/mariadb_ops.md b/generated/dev/docs/mariadb_ops.md deleted file mode 100644 index 14fa2f8..0000000 --- a/generated/dev/docs/mariadb_ops.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](mariadb_params_create.md) -- `create_database` — Создание кластера. Параметры: [Create params](mariadb_params_create.md) -- `create_user` — Создание кластера. Параметры: [Create params](mariadb_params_create.md) -- `delete` -- `delete_database` -- `delete_user` -- `modify` — Изменение кластера. Параметры: [Modify params](mariadb_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/mariadb_outputs.md b/generated/dev/docs/mariadb_outputs.md deleted file mode 100644 index 38f0606..0000000 --- a/generated/dev/docs/mariadb_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/mariadb_params.md b/generated/dev/docs/mariadb_params.md deleted file mode 100644 index 1d0477b..0000000 --- a/generated/dev/docs/mariadb_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Parameters - -- [Create params](mariadb_params_create.md) -- [Modify params](mariadb_params_modify.md) diff --git a/generated/dev/docs/mariadb_params_create.md b/generated/dev/docs/mariadb_params_create.md deleted file mode 100644 index 4f6f74c..0000000 --- a/generated/dev/docs/mariadb_params_create.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
422resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
429ip_space_name_masterstringИмя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster
459s3_uiduuidЭкземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательноref_svc_id=12
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
424resource_cpuinteger500Квота ядра пода (milicores)minvalue=500; maxvalue=4000
425resource_memoryinteger1024Квота памяти пода (MBytes)minvalue=1024; maxvalue=8192
426resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
427resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
428need_external_address_masterbooleanfalseВыделяет внешний (белый) IP для доступа к mastervalue_list=false, true
430ext_backup_schedulestring0 * * * *Не обязательный. Время запуска бекапаregex=^(\*|(\d+|\*\/\d+|\d+(,\d+)*))\s\*\s\*\s\*\s\*$
431app_versionstring9.4.0Версия MySQLvalue_list=8.4.0, 9.4.0
432auto_scalebooleanfalseВключает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услугиvalue_list=false, true
433auto_scale_percentageinteger10Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объемаvalue_list=10, 15, 20
434auto_scale_tech_windowinteger0Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23)value_list=0, 5, 12, 23
435auto_scale_quota_gbinteger1Квота для autoScale
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/mariadb_params_modify.md b/generated/dev/docs/mariadb_params_modify.md deleted file mode 100644 index c17f0d8..0000000 --- a/generated/dev/docs/mariadb_params_modify.md +++ /dev/null @@ -1,25 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Modify params - - - - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
436resource_cpuinteger
437resource_memoryinteger
438resource_instancesinteger
439resource_diskinteger
440need_external_address_masterbooleanvalue_list=false, true
441ip_space_name_master
442ext_backup_schedulestring
443auto_scalebooleanvalue_list=false, true
444auto_scale_percentageinteger
445auto_scale_tech_windowinteger
446auto_scale_quota_gbinteger
diff --git a/generated/dev/docs/mongodb.md b/generated/dev/docs/mongodb.md deleted file mode 100644 index 8f1fa29..0000000 --- a/generated/dev/docs/mongodb.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## MAN - -
-# Инструкция по развертыванию MongoDB через платформу

## 1. Общая информация

MongoDB — документоориентированная распределённая база данных, обеспечивающая высокую доступность, горизонтальное масштабирование и гибкую модель хранения.

### Доступные операции с кластером

* **create** — создание базы
* **delete** — удаление базы данных
* **suspend** — остановка базы данных
* **resume** — запуск базы данных
* **modify** — изменение базы данных

### Доступные операции с пользователями

* **create_user** — создание пользователя
* **modify_user** — модификация пользователя
* **delete_user** — удаление пользователя

---

## 2. Параметры развертывания базы данных

Эти параметры необходимо указать при создании базы данных.

### Платформа для развертывания

Среда, в которой будет развернут кластер. Выбирается из предложенного списка.

### Количество узлов

Оптимально выбирать нечётное количество узлов в кластере MongoDB, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность базы данных даже при отказе одной из нод.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных в гигабайтах.
Пример: `20`

### Выделение внешнего IP для доступа к master

Флаг, определяющий необходимость выделения внешнего IP.
Допустимые значения: `true` или `false`

### Имя ipSpace для публикации внешнего IP

Указывается только если включено выделение внешнего IP.
Пример: `internet-no-antiddos-v1`

---

## 3. Параметры модификации базы данных

Все параметры, которые вы указываете при модификации, являются необязательными — система автоматически подставит ранее сохранённые значения, и при необходимости вы можете изменить их на нужные.

### Количество узлов

Оптимально выбирать нечётное количество узлов в кластере MongoDB, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность базы данных даже при отказе одной из нод.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных указывается в гигабайтах. Его можно увеличить при необходимости, однако уменьшить уже выделенный размер невозможно.
Пример: `20`

### Выделение внешнего IP для доступа к master

Флаг, определяющий необходимость выделения внешнего IP.
Допустимые значения: `true` или `false`

### Имя ipSpace для публикации внешнего IP

Указывается только если включено выделение внешнего IP.
Пример: `internet-no-antiddos-v1`

---

## 3. Параметры создания пользователя

### Имя пользователя

Указывается имя пользователя (любой регистр).
Пример: `readApp`

### Имя базы данных

Название базы, в которой будет создан пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read** — доступ только на чтение
* **readWrite** — чтение и изменение данных
* **dbOwner** — полный контроль над базой данных

---

## 4. Параметры модификации пользователя

### Имя пользователя

Необходимо выбрать существующего пользователя.
Если список пуст, требуется предварительно создать пользователя.

### Имя базы данных

База данных, к которой относится пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read**
* **readWrite**
* **dbOwner**

---

## 5. Параметры удаления пользователя

### Имя пользователя

Выберите пользователя из списка для удаления.

---

## 6. Выходные параметры

После успешного развертывания базы данных платформа возвращает ключевые параметры.

### internalConnect

Внутренний эндпоинт для подключения к кластеру из сервисов, работающих в той же сети.
Используется для внутренних интеграций и системных сервисов.

### externalConnect

Внешний FQDN для подключения к кластеру извне.
Порт подключения — **27017**.

---

## 7. Пример подключения

Перед подключением необходимо установить **mongosh**.

Команда подключения к базе данных:

```
mongosh "mongodb://<username>:<password>@<endpoint_db>:27017/<dbName>"
```

Где:

* `<username>` — имя пользователя
* `<password>` — пароль
* `<endpoint_db>` — internalConnect или externalConnect
* `<dbName>` — имя базы данных

## 8. Дополнительная информация

Сейчас соединение с базой работает без шифрования, и доступ к кластеру осуществляется только по логину и паролю. -
diff --git a/generated/dev/docs/mongodb_example.md b/generated/dev/docs/mongodb_example.md deleted file mode 100644 index c263900..0000000 --- a/generated/dev/docs/mongodb_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Copy-ready manifest (`mongodb_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_mongodb" "baza" { - resource_instances = 1 # Пример: `2` - resource_memory = 1 # Пример: `2048` - resource_cpu = 1 # Пример: `1000` - resource_disk = 1 # Пример: `20` - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - need_external_address_master = false # Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_mongodb.baza.state_params["имя_ключа"] -nubes_mongodb.baza.state_out["имя_ключа"] -nubes_mongodb.baza.state_params_flat["имя_ключа"] -nubes_mongodb.baza.state_out_flat["имя_ключа"] -nubes_mongodb.baza.vault_secrets["имя_ключа"] -nubes_mongodb.baza.vault_url -nubes_mongodb.baza.vault_user_path -nubes_mongodb.baza.vault_fields -``` diff --git a/generated/dev/docs/mongodb_ops.md b/generated/dev/docs/mongodb_ops.md deleted file mode 100644 index 1e923ef..0000000 --- a/generated/dev/docs/mongodb_ops.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](mongodb_params_create.md) -- `create_user` — Создание кластера. Параметры: [Create params](mongodb_params_create.md) -- `delete` -- `delete_user` -- `modify` — Изменение кластера. Параметры: [Modify params](mongodb_params_modify.md) -- `modify_user` — Изменение кластера. Параметры: [Modify params](mongodb_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/mongodb_outputs.md b/generated/dev/docs/mongodb_outputs.md deleted file mode 100644 index 2a6b2dc..0000000 --- a/generated/dev/docs/mongodb_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["internalConnect"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/dev/docs/mongodb_params.md b/generated/dev/docs/mongodb_params.md deleted file mode 100644 index b595ec1..0000000 --- a/generated/dev/docs/mongodb_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Parameters - -- [Create params](mongodb_params_create.md) -- [Modify params](mongodb_params_modify.md) diff --git a/generated/dev/docs/mongodb_params_create.md b/generated/dev/docs/mongodb_params_create.md deleted file mode 100644 index 650eb5e..0000000 --- a/generated/dev/docs/mongodb_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
487resource_instancesintegerПример: `2`minvalue=1; maxvalue=7
588resource_memoryintegerПример: `2048`minvalue=500
589resource_cpuintegerПример: `1000`
590resource_diskintegerПример: `20`
595resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
646ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
645need_external_address_masterbooleanfalseФлаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/mongodb_params_modify.md b/generated/dev/docs/mongodb_params_modify.md deleted file mode 100644 index e00c6cc..0000000 --- a/generated/dev/docs/mongodb_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
648resource_instancesintegerПример: `2`
649resource_memoryintegerПример: `2048`
650resource_cpuintegerПример: `1000`
651resource_diskintegerПример: `20`
652need_external_address_masterbooleanФлаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`
653ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
diff --git a/generated/dev/docs/nextcloud.md b/generated/dev/docs/nextcloud.md deleted file mode 100644 index a494623..0000000 --- a/generated/dev/docs/nextcloud.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## MAN - -
-Ресурсная платформа: k8s. Автоматизация: helm chart -
diff --git a/generated/dev/docs/nextcloud_example.md b/generated/dev/docs/nextcloud_example.md deleted file mode 100644 index c05ddc4..0000000 --- a/generated/dev/docs/nextcloud_example.md +++ /dev/null @@ -1,53 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Copy-ready manifest (`nextcloud_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_nextcloud" "baza" { - psql_uid = "TODO" - redis_uid = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 1000 # Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili - resource_memory = 1024 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 2 # Квота диска (Указывается в GIGAbytes) Диск не может быть меньше 2G (!) - document_server = "collabora" # Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен Размер пода collabora: 1.8 ядра. 2Gi ОЗУ - resource_instances = 1 # Количество узлов Не может пока быть больше одного, так как нужны SC под RWMany - app_version = 32.0.1 -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nextcloud.baza.state_params["имя_ключа"] -nubes_nextcloud.baza.state_out["имя_ключа"] -nubes_nextcloud.baza.state_params_flat["имя_ключа"] -nubes_nextcloud.baza.state_out_flat["имя_ключа"] -nubes_nextcloud.baza.vault_secrets["имя_ключа"] -nubes_nextcloud.baza.vault_url -nubes_nextcloud.baza.vault_user_path -nubes_nextcloud.baza.vault_fields -``` diff --git a/generated/dev/docs/nextcloud_ops.md b/generated/dev/docs/nextcloud_ops.md deleted file mode 100644 index 2dd5b5f..0000000 --- a/generated/dev/docs/nextcloud_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nextcloud_params_create.md) -- `delete` — DEV-Ветка удаления Nextcloud -- `modify` — Изменение кластера. Параметры: [Modify params](nextcloud_params_modify.md) -- `restart` -- `resume` -- `suspend` diff --git a/generated/dev/docs/nextcloud_outputs.md b/generated/dev/docs/nextcloud_outputs.md deleted file mode 100644 index 1a8707b..0000000 --- a/generated/dev/docs/nextcloud_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/nextcloud_params.md b/generated/dev/docs/nextcloud_params.md deleted file mode 100644 index 2c1eb71..0000000 --- a/generated/dev/docs/nextcloud_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Parameters - -- [Create params](nextcloud_params_create.md) -- [Modify params](nextcloud_params_modify.md) diff --git a/generated/dev/docs/nextcloud_params_create.md b/generated/dev/docs/nextcloud_params_create.md deleted file mode 100644 index b3e6a19..0000000 --- a/generated/dev/docs/nextcloud_params_create.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
564psql_uiduuidref_svc_id=90
570redis_uiduuidref_svc_id=91
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
21domainstringweb01Наименование домена. Если будет указан FQDN, то происходят проверки DNS. Если указан поддомен, то будет добавлен в зону services.ngcloud.ru
Можно указать клиентскую DNS-Запись. Важно, чтобы запись смотрела на Ingress кластера
regex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
99resource_cpuinteger1000Квота ядра пода (Указывается в mili). 1 ядро = 1000 Miliminvalue=100; maxvalue=4000
100resource_memoryinteger1024Квота памяти пода (Указывается в Megabytes)minvalue=1024; maxvalue=8192
101resource_diskinteger2Квота диска (Указывается в GIGAbytes)minvalue=2; maxvalue=999
192document_serverstringcollaboraВыбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступенvalue_list=collabora
470resource_instancesinteger1Количество узлов
Не может пока быть больше одного, так как нужны SC под RWMany
minvalue=1; maxvalue=7; value_list=1
569app_version32.0.1value_list=32.0.1
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/nextcloud_params_modify.md b/generated/dev/docs/nextcloud_params_modify.md deleted file mode 100644 index 4da066d..0000000 --- a/generated/dev/docs/nextcloud_params_modify.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Modify params - - - - - - - - - -
IDCodeTypeDescriptionConstraints
178resource_cpuintegerКвота ядра пода (Указывается в mili)minvalue=100; maxvalue=4000
179resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
180resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
547resource_instancesintegerКоличество узлов.
Не может пока быть больше одного, так как нужны SC под RWMany
minvalue=1; maxvalue=7; value_list=1
571app_versionstringНельзя обновляться сразу через несколько версий сразуvalue_list=32.0.1
diff --git a/generated/dev/docs/nifi.md b/generated/dev/docs/nifi.md deleted file mode 100644 index b4f0531..0000000 --- a/generated/dev/docs/nifi.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nifi - -Service ID: `153` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/dev/docs/nifi_example.md b/generated/dev/docs/nifi_example.md deleted file mode 100644 index 2da1321..0000000 --- a/generated/dev/docs/nifi_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_nifi - -Service ID: `153` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Copy-ready manifest (`nifi_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_nifi" "baza" { - resource_realm = "TODO" # Кластер Kubernetes в котором будет развёрнуто приложение - jdbc_drivers = "TODO" # Пример: `https://jdbc.postgresql.org/download/postgresql-42.7.8.jar` - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "nifi-" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 2000 # Пример: `2000` - resource_memory = 4096 # Пример: `2048` - resource_instances = 1 # Пример: `1` - resource_disk = 10 # Пример: `10` - app_version = 2.6.0 # Выбрать из списка -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nifi.baza.state_params["имя_ключа"] -nubes_nifi.baza.state_out["имя_ключа"] -nubes_nifi.baza.state_params_flat["имя_ключа"] -nubes_nifi.baza.state_out_flat["имя_ключа"] -nubes_nifi.baza.vault_secrets["имя_ключа"] -nubes_nifi.baza.vault_url -nubes_nifi.baza.vault_user_path -nubes_nifi.baza.vault_fields -``` diff --git a/generated/dev/docs/nifi_ops.md b/generated/dev/docs/nifi_ops.md deleted file mode 100644 index f135d36..0000000 --- a/generated/dev/docs/nifi_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nifi - -Service ID: `153` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nifi_params_create.md) -- `delete` diff --git a/generated/dev/docs/nifi_outputs.md b/generated/dev/docs/nifi_outputs.md deleted file mode 100644 index d3c1519..0000000 --- a/generated/dev/docs/nifi_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nifi - -Service ID: `153` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/nifi_params.md b/generated/dev/docs/nifi_params.md deleted file mode 100644 index 35b668c..0000000 --- a/generated/dev/docs/nifi_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nifi - -Service ID: `153` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Parameters - -- [Create params](nifi_params_create.md) -- [Modify params](nifi_params_modify.md) diff --git a/generated/dev/docs/nifi_params_create.md b/generated/dev/docs/nifi_params_create.md deleted file mode 100644 index 04fd9b0..0000000 --- a/generated/dev/docs/nifi_params_create.md +++ /dev/null @@ -1,30 +0,0 @@ -# Resource nubes_nifi - -Service ID: `153` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
717resource_realmstringВыбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы
func=getAvailableResourceRealms
718jdbc_driversarray-map-fixedПример: `https://jdbc.postgresql.org/download/postgresql-42.7.8.jar`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
711domainstringnifi-Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
712resource_cpuinteger2000Указывается в Milicores
`1000` Mili == `1` Ядро
minvalue=2000; maxvalue=8000
713resource_memoryinteger4096Указывается в Megabytesminvalue=2048; maxvalue=16384
714resource_instancesinteger1Пример: `1`minvalue=1; maxvalue=1; value_list=1
715resource_diskinteger10Указывается в Gigabytesminvalue=1; maxvalue=999
716app_versionstring2.6.0Выбрать из спискаvalue_list=2.6.0
diff --git a/generated/dev/docs/nifi_params_modify.md b/generated/dev/docs/nifi_params_modify.md deleted file mode 100644 index 9b682b0..0000000 --- a/generated/dev/docs/nifi_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_nifi - -Service ID: `153` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/nodejs.md b/generated/dev/docs/nodejs.md deleted file mode 100644 index a1c6804..0000000 --- a/generated/dev/docs/nodejs.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## MAN - -
-Развертывает контейнер в k8s кластере с node, который можно использовать для запуска своих приложений.
Приложение должно быть доступно по ссылки в git репозитории, которая является входным параметром. -
diff --git a/generated/dev/docs/nodejs_example.md b/generated/dev/docs/nodejs_example.md deleted file mode 100644 index 9196079..0000000 --- a/generated/dev/docs/nodejs_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Copy-ready manifest (`nodejs_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_nodejs" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - git_path = "https://github.com/xahys/testnode.git" # Путь до Git, который будет webroot для сайта - resource_cpu = 500 # Квота ядра пода (milicores). 1000Mili = 1 Ядро - resource_memory = 1024 # Квота памяти пода (MBytes) - resource_instances = 1 # Количество узлов - app_version = 23 # Версия приложения -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nodejs.baza.state_params["имя_ключа"] -nubes_nodejs.baza.state_out["имя_ключа"] -nubes_nodejs.baza.state_params_flat["имя_ключа"] -nubes_nodejs.baza.state_out_flat["имя_ключа"] -nubes_nodejs.baza.vault_secrets["имя_ключа"] -nubes_nodejs.baza.vault_url -nubes_nodejs.baza.vault_user_path -nubes_nodejs.baza.vault_fields -``` diff --git a/generated/dev/docs/nodejs_ops.md b/generated/dev/docs/nodejs_ops.md deleted file mode 100644 index de1e172..0000000 --- a/generated/dev/docs/nodejs_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nodejs_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](nodejs_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/dev/docs/nodejs_outputs.md b/generated/dev/docs/nodejs_outputs.md deleted file mode 100644 index 5fa8a14..0000000 --- a/generated/dev/docs/nodejs_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/dev/docs/nodejs_params.md b/generated/dev/docs/nodejs_params.md deleted file mode 100644 index daf96ca..0000000 --- a/generated/dev/docs/nodejs_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Parameters - -- [Create params](nodejs_params_create.md) -- [Modify params](nodejs_params_modify.md) diff --git a/generated/dev/docs/nodejs_params_create.md b/generated/dev/docs/nodejs_params_create.md deleted file mode 100644 index 1bf4766..0000000 --- a/generated/dev/docs/nodejs_params_create.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
151health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет
152json_envjsonМассив переменных, будут переданы в env приложения
156resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
149domainstringweb01Наименование поддомена, будет добавлено в nodejs.dev.nubes.ruregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
150git_pathstringhttps://github.com/xahys/testnode.gitПуть до Git, который будет webroot для сайта
153resource_cpuinteger500Квота ядра пода (milicores). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
154resource_memoryinteger1024Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
155resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
270app_versionstring23Версия приложенияregex=^(\d){2}$; value_list=18, 20, 22, 23
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/nodejs_params_modify.md b/generated/dev/docs/nodejs_params_modify.md deleted file mode 100644 index 89a753e..0000000 --- a/generated/dev/docs/nodejs_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
157git_pathstringПуть до Git, который будет webroot для сайта
158health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код.
159json_envjsonМассив переменных, будут переданы в env приложенияmaxlength=2048
160resource_cpuintegerКвота ядра пода (Указывается в mili) 1000Mili = 1 ядроminvalue=100; maxvalue=4000
161resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
162resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
271app_versionstringВерсия приложенияregex=^(\d){2}$; value_list=18, 20, 22, 23
diff --git a/generated/dev/docs/nodered.md b/generated/dev/docs/nodered.md deleted file mode 100644 index 54ecff3..0000000 --- a/generated/dev/docs/nodered.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/dev/docs/nodered_example.md b/generated/dev/docs/nodered_example.md deleted file mode 100644 index 6a5a7f5..0000000 --- a/generated/dev/docs/nodered_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Copy-ready manifest (`nodered_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_nodered" "baza" { - resource_realm = "TODO" # Платформа для развертывания - domain = "TODO" # Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nodered.baza.state_params["имя_ключа"] -nubes_nodered.baza.state_out["имя_ключа"] -nubes_nodered.baza.state_params_flat["имя_ключа"] -nubes_nodered.baza.state_out_flat["имя_ключа"] -nubes_nodered.baza.vault_secrets["имя_ключа"] -nubes_nodered.baza.vault_url -nubes_nodered.baza.vault_user_path -nubes_nodered.baza.vault_fields -``` diff --git a/generated/dev/docs/nodered_ops.md b/generated/dev/docs/nodered_ops.md deleted file mode 100644 index 2d6074e..0000000 --- a/generated/dev/docs/nodered_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nodered_params_create.md) -- `delete` diff --git a/generated/dev/docs/nodered_outputs.md b/generated/dev/docs/nodered_outputs.md deleted file mode 100644 index 74e4213..0000000 --- a/generated/dev/docs/nodered_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/nodered_params.md b/generated/dev/docs/nodered_params.md deleted file mode 100644 index 60a797d..0000000 --- a/generated/dev/docs/nodered_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Parameters - -- [Create params](nodered_params_create.md) -- [Modify params](nodered_params_modify.md) diff --git a/generated/dev/docs/nodered_params_create.md b/generated/dev/docs/nodered_params_create.md deleted file mode 100644 index f976ccb..0000000 --- a/generated/dev/docs/nodered_params_create.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
196resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
197domainstringНаименование поддомена, будет добавлено в k8stemplate.dev.nubes.ruregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
193resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
194resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
195resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
323resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
diff --git a/generated/dev/docs/nodered_params_modify.md b/generated/dev/docs/nodered_params_modify.md deleted file mode 100644 index be00f3b..0000000 --- a/generated/dev/docs/nodered_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/pgadmin.md b/generated/dev/docs/pgadmin.md deleted file mode 100644 index 5c2feaf..0000000 --- a/generated/dev/docs/pgadmin.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## MAN - -
-Инструмент с графическим интерфейсом для управления базами данных PostgreSQL -
diff --git a/generated/dev/docs/pgadmin_example.md b/generated/dev/docs/pgadmin_example.md deleted file mode 100644 index ec4edc2..0000000 --- a/generated/dev/docs/pgadmin_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Copy-ready manifest (`pgadmin_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_pgadmin" "baza" { - resource_realm = "TODO" # Платформа для развертывания - login = "TODO" # Логин для подключения к pgAdmin, в формате email (login@email.net) - password = "TODO" # Пароль для подключения к pgAdmin - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 500 # Квота ядра пода (milicores). 1000Mili = 1 Ядро - resource_memory = 512 # Квота памяти пода (MBytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_pgadmin.baza.state_params["имя_ключа"] -nubes_pgadmin.baza.state_out["имя_ключа"] -nubes_pgadmin.baza.state_params_flat["имя_ключа"] -nubes_pgadmin.baza.state_out_flat["имя_ключа"] -nubes_pgadmin.baza.vault_secrets["имя_ключа"] -nubes_pgadmin.baza.vault_url -nubes_pgadmin.baza.vault_user_path -nubes_pgadmin.baza.vault_fields -``` diff --git a/generated/dev/docs/pgadmin_ops.md b/generated/dev/docs/pgadmin_ops.md deleted file mode 100644 index 7449f5e..0000000 --- a/generated/dev/docs/pgadmin_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](pgadmin_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](pgadmin_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/dev/docs/pgadmin_outputs.md b/generated/dev/docs/pgadmin_outputs.md deleted file mode 100644 index a88297a..0000000 --- a/generated/dev/docs/pgadmin_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/dev/docs/pgadmin_params.md b/generated/dev/docs/pgadmin_params.md deleted file mode 100644 index 3afd95c..0000000 --- a/generated/dev/docs/pgadmin_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Parameters - -- [Create params](pgadmin_params_create.md) -- [Modify params](pgadmin_params_modify.md) diff --git a/generated/dev/docs/pgadmin_params_create.md b/generated/dev/docs/pgadmin_params_create.md deleted file mode 100644 index f87da9c..0000000 --- a/generated/dev/docs/pgadmin_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
169resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
170loginstringЛогин для подключения к pgAdmin, в формате email (login@email.net)regex=^([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)$; maxlength=255; minlength=3
171passwordstringПароль для подключения к pgAdmin
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
164domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
165resource_cpuinteger500Квота ядра пода (milicores). 1000Mili = 1 Ядроminvalue=500; maxvalue=4000
166resource_memoryinteger512Квота памяти пода (MBytes)minvalue=512; maxvalue=8192
167resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/pgadmin_params_modify.md b/generated/dev/docs/pgadmin_params_modify.md deleted file mode 100644 index 0b7613e..0000000 --- a/generated/dev/docs/pgadmin_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
172resource_cpuintegerКвота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
173resource_memoryintegerКвота памяти пода (MBytes)minvalue=128; maxvalue=8192
174resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
diff --git a/generated/dev/docs/postgres.md b/generated/dev/docs/postgres.md deleted file mode 100644 index 61e7668..0000000 --- a/generated/dev/docs/postgres.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## MAN - -
-# Инструкция по развертыванию PostgreSQL через платформу

---
## 1. Общая информация

PostgreSQL — это надёжная объектно-реляционная СУБД с открытым исходным кодом, поддерживающая расширенный набор функций, транзакции и хранение сложных типов данных. Развёртывание полностью автоматизировано платформой на базе Zalando Postgres Operator с использованием Kubernetes.

## Доступные операции

- **create** — Создание кластера
- **delete** — Удаление кластера
- **modify** — Модификация кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера
- **restart** — Перезапуск кластера
- **recovery** — Восстановление из резервной копии

- **create_user** — Создание пользователя
- **delete_user** — Удаление пользователя

- **create_database** — Создание базы данных
- **delete_database** — Удаление базы данных


---
## 2. Параметры развертывания кластера

Ниже перечислены параметры, которые необходимо указать при создании ресурса PostgreSQL:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество инстансов (реплик) в кластере PostgreSQL. Пример: `2` (master + slave).

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных в гигабайтах. Пример: `20`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`

* **Выделяет внешний IP для доступа к slave:**
Флаг для выделения внешнего IP для slave (реплики чтения). Работает, если slave присутствует в кластере.

* **Имя ipSpace для публикации внешнего IP slave:**
Если включен параметр для slave, то поле необходимо заполнить.

* **UUID экземпляра услуги S3:**
UUID экземпляра S3 для хранения резервных копий.

* **Версия PostgreSQL:**
Версия PostgreSQL для развертывания. Пример: `16`

* **Расписание бэкапов (ext_BACKUP_SCHEDULE):**
Необязательный. Cron-выражение для времени запуска бэкапов. По умолчанию: `0 0 * * *` (ежедневно в полночь).

* **Количество сохраняемых бэкапов (ext_BACKUP_NUM_TO_RETAIN):**
Необязательный. Количество сохраняемых бэкапов. По умолчанию: `7`

* **PgPooler (master / slave):**
Флаги включения PgBouncer для подключений на запись и чтение. При включении создаётся отдельный под.

* **Разрешить подключение без SSL (allowNoSSL):**
По умолчанию подключение с sslmode=require. При `true` разрешается подключение без SSL.

* **Автоскейлинг PV (autoScale):**
Включает автоскейлинг тома. Требует настройки autoScalePercentage, autoScaleTechWindow, autoScaleQuotaGb.

* **Дополнительные параметры PostgreSQL (jsonParameters):**
JSON с переменными конфигурации PostgreSQL. Документация: https://www.postgresql.org/docs/current/runtime-config.html

---
## 3. Выходные параметры

После успешного развертывания ресурса PostgreSQL платформа возвращает ряд параметров.

#### externalConnect

Внешние эндпоинты для подключения к кластеру:
- **master** — для операций записи (host: `write.${namespace}`, port: 5432)
- **slave** — для операций чтения (host: `read.${namespace}`, port: 5432)

Пример ответа платформы:

```json
{
"slave": {
"ip": "",
"fqdn": "",
"uuid": "",
"isExternal": false
},
"master": {
"ip": "<ip>",
"fqdn": "write.<namespace>.<cluster-domain>",
"uuid": "<uuid>",
"isExternal": false
}
}
```

Поля: `ip` — внешний IP; `fqdn` — полное имя хоста; `uuid` — идентификатор; `isExternal` — признак внешнего доступа.

#### internalConnect

Внутренние эндпоинты (FQDN) для подключения из других сервисов внутри той же сети Kubernetes.

Пример ответа платформы:

```json
{
"slave": "",
"master": {
"slave": "",
"master": {
"slave": "",
"master": "postgresqlk8s-master.<namespace>.svc.cluster.local"
}
}
}
```

Для подключения используйте значение `master.master.master` (host для записи) или соответствующее значение slave (host для чтения).

Для подключения используется порт **5432**.

---
## 4. Управление пользователями

### create_user — Создание пользователя

* **Имя пользователя (username):**
Имя создаваемого пользователя. Используется для подключения к базе и настройки прав.
Пример: `myapp_user`

* **Роль (role):**
Тип роли пользователя. Допустимые значения:
- `app_user` — базовые права для DML-операций (SELECT, INSERT, UPDATE, DELETE)
- `ddl_user` — расширенные права: createdb, createrole (управление базами и ролями)

Защищённые имена, которые нельзя использовать: `admin`, `postgres`, `standby`.

### delete_user — Удаление пользователя

* **Имя пользователя (username):**
Имя удаляемого пользователя. Пример: `myapp_user`

Пользователя нельзя удалить, если он является владельцем базы данных. Сначала удалите или передайте владение базами данных другому пользователю.

---
## 5. Управление базами данных

### create_database — Создание базы данных

* **Имя базы данных (dbName):**
Название создаваемой базы данных. Пример: `myapp_db`

* **Владелец базы данных (dbOwner):**
Имя пользователя-владельца базы. Должен существовать в кластере (создан через create_user). Пример: `myapp_user`

### delete_database — Удаление базы данных

* **Имя базы данных (dbName):**
Название удаляемой базы данных. Пример: `myapp_db`
-
diff --git a/generated/dev/docs/postgres_example.md b/generated/dev/docs/postgres_example.md deleted file mode 100644 index 8a60f95..0000000 --- a/generated/dev/docs/postgres_example.md +++ /dev/null @@ -1,63 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Copy-ready manifest (`postgres_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_postgres" "baza" { - s3_uid = "TODO" # Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_instances = 1 # Количество узлов - resource_memory = 512 # Квота памяти пода (MBytes) - resource_cpu = 500 # Квота ядра пода (milicores) - resource_disk = 10 # Квота диска (Указывается в GIGAbytes) - need_external_address_master = false # Выделяет внешний (белый) IP для доступа к master - need_external_address_slave = false # Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть - ext_backup_schedule = "0 0 * * *" # Не обязательный. Время запуска бекапа - ext_backup_num_to_retain = 7 # Не обязательный. Количество сохраняемых бекапов - app_version = 17 # Версия PostgreSQL - json_parameters = { "log_connections": "off", "log_disconnections": "off" } # Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html - enable_pg_pooler_master = false # Включает pgPooler (на запись). Будет создан новый под - enable_pg_pooler_slave = false # Включает pgPooler (на чтение). Будет создан новый под - allow_no_ssl = false # По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр - auto_scale = false # Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги - auto_scale_percentage = 10 # Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема - auto_scale_tech_window = 0 # Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) - auto_scale_quota_gb = 1 # Квота для autoScale -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_postgres.baza.state_params["имя_ключа"] -nubes_postgres.baza.state_out["имя_ключа"] -nubes_postgres.baza.state_params_flat["имя_ключа"] -nubes_postgres.baza.state_out_flat["имя_ключа"] -nubes_postgres.baza.vault_secrets["имя_ключа"] -nubes_postgres.baza.vault_url -nubes_postgres.baza.vault_user_path -nubes_postgres.baza.vault_fields -``` diff --git a/generated/dev/docs/postgres_ops.md b/generated/dev/docs/postgres_ops.md deleted file mode 100644 index 601c4bd..0000000 --- a/generated/dev/docs/postgres_ops.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](postgres_params_create.md) -- `create_database` — Создание кластера. Параметры: [Create params](postgres_params_create.md) -- `create_user` — Создание кластера. Параметры: [Create params](postgres_params_create.md) -- `delete` -- `delete_database` -- `delete_user` -- `modify` — Изменение кластера. Параметры: [Modify params](postgres_params_modify.md) -- `recovery` -- `restart` — ВНИМАНИЕ - Рестарт предполагает УДАЛЕНИЕ подов. Может быть полная поломка. Крайне осторожно запускать при работе -- `resume` -- `suspend` diff --git a/generated/dev/docs/postgres_outputs.md b/generated/dev/docs/postgres_outputs.md deleted file mode 100644 index f07b697..0000000 --- a/generated/dev/docs/postgres_outputs.md +++ /dev/null @@ -1,65 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.master"]` -- `state_out_flat["externalConnect.master.fqdn"]` -- `state_out_flat["externalConnect.master.ip"]` -- `state_out_flat["externalConnect.master.isExternal"]` -- `state_out_flat["externalConnect.master.uuid"]` -- `state_out_flat["externalConnect.slave"]` -- `state_out_flat["externalConnect.slave.fqdn"]` -- `state_out_flat["externalConnect.slave.ip"]` -- `state_out_flat["externalConnect.slave.isExternal"]` -- `state_out_flat["externalConnect.slave.uuid"]` -- `state_out_flat["internalConnect"]` -- `state_out_flat["internalConnect.master"]` -- `state_out_flat["internalConnect.slave"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.k8spostgresql"]` -- `state_out_flat["monitoring.k8spostgresql.url"]` -- `state_out_flat["monitoring.k8spostgresqlbackup"]` -- `state_out_flat["monitoring.k8spostgresqlbackup.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` -- `vault_secrets["standbyPass"]` -- `vault_secrets["standbyUser"]` - -### Пример для связки с Lucee/NodeJS - -```hcl -testds_connectionString = "jdbc:postgresql://${nubes_postgres.db2.state_out_flat["internalConnect.master"]}:5432/postgres?sslmode=require" -testds_username = nubes_postgres.db2.vault_secrets["adminUser"] -testds_password = nubes_postgres.db2.vault_secrets["adminPass"] -``` diff --git a/generated/dev/docs/postgres_params.md b/generated/dev/docs/postgres_params.md deleted file mode 100644 index b44e9f4..0000000 --- a/generated/dev/docs/postgres_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Parameters - -- [Create params](postgres_params_create.md) -- [Modify params](postgres_params_modify.md) diff --git a/generated/dev/docs/postgres_params_create.md b/generated/dev/docs/postgres_params_create.md deleted file mode 100644 index 2eb0637..0000000 --- a/generated/dev/docs/postgres_params_create.md +++ /dev/null @@ -1,55 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
23s3_uiduuidЭкземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательноref_svc_id=12
102resource_realmstringКластер Kubernetes, на котором будет развернут экземплярfunc=getAvailableResourceRealms
337ip_space_name_masterstringИмя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`
338ip_space_name_slavestringИмя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
80resource_instancesinteger1Количество узлов в кластере. 1,3,5,7minvalue=1; maxvalue=7; regex=^[1357]$
81resource_memoryinteger512Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
82resource_cpuinteger500Квота ядра пода (milicores)minvalue=100; maxvalue=4000
83resource_disk10Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
145need_external_address_masterbooleanfalseВыделяет внешний (белый) IP для доступа к mastervalue_list=false, true
146need_external_address_slavebooleanfalseВыделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе естьvalue_list=false, true
265ext_backup_schedulestring0 0 * * *Не обязательный. Время запуска бекапаregex=^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$
266ext_backup_num_to_retaininteger7Не обязательный. Количество сохраняемых бекаповminvalue=1; maxvalue=99
310app_versionstring17Версия PostgreSQLvalue_list=17, 16
311json_parametersjson{ "log_connections": "off", "log_disconnections": "off" }Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.htmlmaxlength=2048
312enable_pg_pooler_masterbooleanfalseВключает pgPooler (на запись). Будет создан новый подvalue_list=false, true
313enable_pg_pooler_slavebooleanfalseВключает pgPooler (на чтение). Будет создан новый подvalue_list=false, true
314allow_no_sslbooleanfalseПо умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметрvalue_list=false, true
329auto_scalebooleanfalseВключает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услугиvalue_list=false, true
330auto_scale_percentageinteger10Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объемаvalue_list=10, 15, 20
331auto_scale_tech_windowinteger0Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23)value_list=0, 5, 12, 23
339auto_scale_quota_gbstring1Квота для autoScale
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/postgres_params_modify.md b/generated/dev/docs/postgres_params_modify.md deleted file mode 100644 index a61d69e..0000000 --- a/generated/dev/docs/postgres_params_modify.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Modify params - - - - - - - - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
91resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
92resource_memoryintegerКвота памяти пода (MBytes)minvalue=128; maxvalue=8192
93resource_cpuintegerКвота ядра пода (milicores)minvalue=100; maxvalue=4000
94resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
147need_external_address_masterbooleanВыделяет внешний IP для доступа к mastervalue_list=false, true
148need_external_address_slavebooleanВыделяет внешний IP для доступа к slave. Действует, если slave в принципе естьvalue_list=false, true
267ext_backup_schedulestringНе обязательный. Время запуска бекапаregex=^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$
268ext_backup_num_to_retainintegerНе обязательный. Количество сохраняемых бекаповminvalue=1; maxvalue=99
315app_versionstringВерсия PostgreSQL. Нельзя опускать внизvalue_list=17, 16
316json_parametersjsonМассив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.htmlmaxlength=2048
317enable_pg_pooler_masterbooleanВключает pgPooler (на запись). Будет создан новый подvalue_list=false, true
318enable_pg_pooler_slavebooleanВключает pgPooler (на чтение). Будет создан новый подvalue_list=false, true
319allow_no_sslbooleanПо умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметрvalue_list=false, true
541ip_space_name_masterstringИмя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`
542ip_space_name_slavestringИмя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave
diff --git a/generated/dev/docs/rabbitmq.md b/generated/dev/docs/rabbitmq.md deleted file mode 100644 index d0e5af3..0000000 --- a/generated/dev/docs/rabbitmq.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## MAN - -
-# Инструкция по развертыванию RabbitMQ через платформу

---
## 1. Общая информация
RabbitMQ — это брокер сообщений с открытым исходным кодом, который обеспечивает надёжную доставку сообщений между приложениями.
Позволяет надёжно передавать сообщения между сервисами и системами, интегрироваться с внешними решениями и использовать как внутренние, так и защищённые TLS-подключения. Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание кластера
- **modify** — Изменение параметров кластера
- **delete** — Удаление кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера


---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса RabbitMQ:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество реплик в кластере RabbitMQ. При значении больше 1 создаётся кластер с репликацией для обеспечения высокой доступности.
Пример: `1` (single node) или `3` (кластер с репликацией)

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных RabbitMQ в гигабайтах. Пример: `50`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-узлу. При включении создаётся Service типа LoadBalancer и настраивается VIP на порту 5672.
Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`


---
## 3. Модификация кластера
Операция **modify** позволяет изменить параметры существующего кластера RabbitMQ.

**Изменяемые параметры:**
* **Квота (megabyte) памяти пода** — можно увеличить или уменьшить
* **Квота (millicore) ядра пода** — можно увеличить или уменьшить
* **Размер (gigabyte) диска для базы данных** — можно только увеличить (уменьшение не поддерживается)
* **Количество узлов в сети** — можно только увеличить (уменьшение не поддерживается)
* **Выделяет внешний IP для доступа к master** — можно включить или выключить
* **Имя ipSpace для публикации внешнего IP master** — можно изменить при включенном внешнем IP

**Ограничения:**
* Уменьшение размера диска не поддерживается
* Уменьшение количества реплик не поддерживается

---
## 4. Выходные параметры
После успешного развертывания ресурса RabbitMQ платформа возвращает ряд параметров в разделе "Поля состояния (сгенерированные значения)":

**clusterDomain**
Домен кластера Kubernetes, в котором развернут RabbitMQ.
Пример: `cluster.local`

**inernalConnect**
Внутренние эндпоинты для подключения к кластеру RabbitMQ из других сервисов, развернутых внутри той же сети.
Содержит:
* **master** — FQDN для подключения к кластеру. Пример: `rabbitmqk8s.{namespace}.svc.{clusterDomain}`

**externalConnect**
Внешние эндпоинты для подключения к кластеру RabbitMQ извне.
Содержит объекты с полями:
* **admin** — доступ к веб-интерфейсу управления:
* `fqdn` — полное доменное имя для веб-интерфейса. Пример: `admin.{namespace}.{domain}`
* `ip` — IP-адрес
* **master** — доступ к AMQP протоколу (если включен внешний IP):
* `fqdn` — полное доменное имя для AMQP. Пример: `write.{namespace}.{domain}`
* `ip` — IP-адрес

**monitoring**
Информация о дашбордах мониторинга:
* **allDashboards** — URL для доступа ко всем дашбордам Grafana

Для подключения используются следующие порты:

* **5672** — AMQP протокол (внутренний и внешний доступ, если включен внешний IP)
* **15672** — веб-интерфейс управления (доступен через Ingress по HTTPS)

**Учётные данные**
Данные для подключения к RabbitMQ доступны в разделе "Учётные данные":
* **adminUser** — имя пользователя администратора
* **adminPass** — пароль администратора


---
## 5. Примеры подключения через консоль (rabbitmqadmin)

### Работа с очередями через rabbitmqadmin

Для работы с RabbitMQ через консоль используется утилита `rabbitmqadmin`. Установите её или используйте образ с предустановленной утилитой.

Задайте переменные окружения с учётными данными:

```bash
export RABBITMQ_USERNAME=<adminUser>
export RABBITMQ_PASSWORD=<adminPass>
export RABBIT_HOST=<host>
```

Где:
* `<adminUser>` и `<adminPass>` — учётные данные из раздела "Учётные данные"
* `<host>` — адрес для подключения:
* Для внешнего подключения: `externalConnect.admin.fqdn` или `externalConnect.master.fqdn`

**Создание очереди:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
declare queue name=healthcheck durable=false
```

**Листинг очередей:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
list queues
```

**Отправка сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
publish exchange=amq.default routing_key=healthcheck payload="ping-$(date +%s)"
```

**Чтение сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
get queue=healthcheck ackmode=ack_requeue_false
```

---
## 6. Дополнительная информация
Для подключения к кластеру RabbitMQ используйте полученные эндпоинты из раздела "Поля состояния (сгенерированные значения)" и учётные данные из раздела "Учётные данные".

Веб-интерфейс управления доступен по адресу, указанному в параметре `externalConnect.admin.fqdn` через HTTPS.

Для внутреннего подключения используйте адрес из `inernalConnect.master` на порту 5672.

--- -
diff --git a/generated/dev/docs/rabbitmq_example.md b/generated/dev/docs/rabbitmq_example.md deleted file mode 100644 index b5fc1fe..0000000 --- a/generated/dev/docs/rabbitmq_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Copy-ready manifest (`rabbitmq_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_rabbitmq" "baza" { - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 1000 # Пример: `2000` - resource_memory = 1124 # Пример: `2048` - resource_disk = 30 # Пример: `20` - resource_instances = 1 # Пример: `1` - need_external_address_master = false # Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_rabbitmq.baza.state_params["имя_ключа"] -nubes_rabbitmq.baza.state_out["имя_ключа"] -nubes_rabbitmq.baza.state_params_flat["имя_ключа"] -nubes_rabbitmq.baza.state_out_flat["имя_ключа"] -nubes_rabbitmq.baza.vault_secrets["имя_ключа"] -nubes_rabbitmq.baza.vault_url -nubes_rabbitmq.baza.vault_user_path -nubes_rabbitmq.baza.vault_fields -``` diff --git a/generated/dev/docs/rabbitmq_ops.md b/generated/dev/docs/rabbitmq_ops.md deleted file mode 100644 index fe63cf6..0000000 --- a/generated/dev/docs/rabbitmq_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](rabbitmq_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](rabbitmq_params_modify.md) -- `resume` -- `suspend` — Пока не работает из за того что RabbitmqCluster нельзя занулить diff --git a/generated/dev/docs/rabbitmq_outputs.md b/generated/dev/docs/rabbitmq_outputs.md deleted file mode 100644 index 30d870e..0000000 --- a/generated/dev/docs/rabbitmq_outputs.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["clusterDomain"]` -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.admin"]` -- `state_out_flat["externalConnect.admin.fqdn"]` -- `state_out_flat["externalConnect.admin.ip"]` -- `state_out_flat["externalConnect.admin.isExternal"]` -- `state_out_flat["externalConnect.admin.uuid"]` -- `state_out_flat["inernalConnect"]` -- `state_out_flat["inernalConnect.master"]` -- `state_out_flat["inernalConnect.slave"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` - diff --git a/generated/dev/docs/rabbitmq_params.md b/generated/dev/docs/rabbitmq_params.md deleted file mode 100644 index b743d18..0000000 --- a/generated/dev/docs/rabbitmq_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Parameters - -- [Create params](rabbitmq_params_create.md) -- [Modify params](rabbitmq_params_modify.md) diff --git a/generated/dev/docs/rabbitmq_params_create.md b/generated/dev/docs/rabbitmq_params_create.md deleted file mode 100644 index 1a1b21f..0000000 --- a/generated/dev/docs/rabbitmq_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
119resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
543ip_space_name_masterstringПример: `internet-no-antiddos-v1`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
116resource_cpuinteger1000Пример: `2000`minvalue=500; maxvalue=4000
117resource_memoryinteger1124Пример: `2048`minvalue=512; maxvalue=8192
118resource_diskinteger30Пример: `20`minvalue=5; maxvalue=999
224resource_instancesinteger1Пример: `1`minvalue=1; maxvalue=7
225need_external_address_masterbooleanfalseФлаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`value_list=false, true
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/rabbitmq_params_modify.md b/generated/dev/docs/rabbitmq_params_modify.md deleted file mode 100644 index 6df624c..0000000 --- a/generated/dev/docs/rabbitmq_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
304resource_cpuintegerПример: `2000`minvalue=500; maxvalue=4000
305resource_memoryintegerПример: `2048`minvalue=512; maxvalue=8192
306resource_diskintegerПример: `20`minvalue=1; maxvalue=999
307resource_instancesintegerПример: `1`minvalue=1; maxvalue=7
308need_external_address_masterbooleanВыделяет внешний (белый) IP для доступа к mastervalue_list=false, true
545ip_space_name_masterstringПример: `internet-no-antiddos-v1`
diff --git a/generated/dev/docs/redis.md b/generated/dev/docs/redis.md deleted file mode 100644 index 4dfd2ea..0000000 --- a/generated/dev/docs/redis.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## MAN - -
-Redis кластер. Под кеши.
Ресурсная платформа: k8s.
Автоматизация: k8s operator
port 6379 -
diff --git a/generated/dev/docs/redis_example.md b/generated/dev/docs/redis_example.md deleted file mode 100644 index 3e52da0..0000000 --- a/generated/dev/docs/redis_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Copy-ready manifest (`redis_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_redis" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 1000 # Квота ядра пода (Указывается в mili) - resource_memory = 1024 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 30 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - need_external_address_master = false # Выделяет внешний IP для доступа к master - need_external_address_slave = false # Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_redis.baza.state_params["имя_ключа"] -nubes_redis.baza.state_out["имя_ключа"] -nubes_redis.baza.state_params_flat["имя_ключа"] -nubes_redis.baza.state_out_flat["имя_ключа"] -nubes_redis.baza.vault_secrets["имя_ключа"] -nubes_redis.baza.vault_url -nubes_redis.baza.vault_user_path -nubes_redis.baza.vault_fields -``` diff --git a/generated/dev/docs/redis_ops.md b/generated/dev/docs/redis_ops.md deleted file mode 100644 index d5d813c..0000000 --- a/generated/dev/docs/redis_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](redis_params_create.md) -- `delete` diff --git a/generated/dev/docs/redis_outputs.md b/generated/dev/docs/redis_outputs.md deleted file mode 100644 index c735f67..0000000 --- a/generated/dev/docs/redis_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/redis_params.md b/generated/dev/docs/redis_params.md deleted file mode 100644 index 131dd5e..0000000 --- a/generated/dev/docs/redis_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Parameters - -- [Create params](redis_params_create.md) -- [Modify params](redis_params_modify.md) diff --git a/generated/dev/docs/redis_params_create.md b/generated/dev/docs/redis_params_create.md deleted file mode 100644 index 2dccb7e..0000000 --- a/generated/dev/docs/redis_params_create.md +++ /dev/null @@ -1,31 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
182resource_realmstringНаименование кластера Kubernetes для подключения
func=getAvailableResourceRealms
548ip_space_name_masterstringИмя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster
549ip_space_name_slavestringИмя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
112resource_cpuinteger1000Квота ядра пода (Указывается в mili)minvalue=500; maxvalue=4000
113resource_memoryinteger1024Квота памяти пода (Указывается в Megabytes)minvalue=512; maxvalue=8192
114resource_diskinteger30Квота диска (Указывается в GIGAbytes)minvalue=10; maxvalue=999
181resource_instancesinteger1Количество узлов в сети. Если выделить больше 1 ноды, будет добавлено дополнительно 3 Sentinel нодыminvalue=1; maxvalue=7
183need_external_address_masterbooleanfalseВыделяет внешний IP для доступа к mastervalue_list=false, true
184need_external_address_slavebooleanfalseВыделяет внешний IP для доступа к slave. Будет работать если slave в целом естьvalue_list=false, true
diff --git a/generated/dev/docs/redis_params_modify.md b/generated/dev/docs/redis_params_modify.md deleted file mode 100644 index 7461280..0000000 --- a/generated/dev/docs/redis_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/s3.md b/generated/dev/docs/s3.md deleted file mode 100644 index 15a87a0..0000000 --- a/generated/dev/docs/s3.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## MAN - -
-Руководство доступно по ссылке:
https://docs.s3.msk-1.ngcloud.ru/s3/s3.description.html -
diff --git a/generated/dev/docs/s3_example.md b/generated/dev/docs/s3_example.md deleted file mode 100644 index c182be4..0000000 --- a/generated/dev/docs/s3_example.md +++ /dev/null @@ -1,44 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Copy-ready manifest (`s3_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_s3" "baza" { - resource_realm = "TODO" # Платформа для развертывания - display_name = "TODO" # Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_s3.baza.state_params["имя_ключа"] -nubes_s3.baza.state_out["имя_ключа"] -nubes_s3.baza.state_params_flat["имя_ключа"] -nubes_s3.baza.state_out_flat["имя_ключа"] -nubes_s3.baza.vault_secrets["имя_ключа"] -nubes_s3.baza.vault_url -nubes_s3.baza.vault_user_path -nubes_s3.baza.vault_fields -``` diff --git a/generated/dev/docs/s3_ops.md b/generated/dev/docs/s3_ops.md deleted file mode 100644 index d030e69..0000000 --- a/generated/dev/docs/s3_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](s3_params_create.md) -- `create_sub_user` — Создание кластера. Параметры: [Create params](s3_params_create.md) -- `delete` -- `delete_sub_user` -- `modify` — Изменение кластера. Параметры: [Modify params](s3_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/s3_outputs.md b/generated/dev/docs/s3_outputs.md deleted file mode 100644 index e1cdeb2..0000000 --- a/generated/dev/docs/s3_outputs.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dtEndTrial"]` -- `state_out_flat["dtStartTrial"]` -- `state_out_flat["isTrial"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.s3ceph"]` -- `state_out_flat["monitoring.s3ceph.url"]` -- `state_out_flat["urlConnect"]` - -### `vault_secrets` ключи - -- `vault_secrets["1325_access_key"]` -- `vault_secrets["1325_secret_key"]` -- `vault_secrets["1325_technicalS3Backup_access_key"]` -- `vault_secrets["1325_technicalS3Backup_secret_key"]` - diff --git a/generated/dev/docs/s3_params.md b/generated/dev/docs/s3_params.md deleted file mode 100644 index d61aced..0000000 --- a/generated/dev/docs/s3_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Parameters - -- [Create params](s3_params_create.md) -- [Modify params](s3_params_modify.md) diff --git a/generated/dev/docs/s3_params_create.md b/generated/dev/docs/s3_params_create.md deleted file mode 100644 index 743e44f..0000000 --- a/generated/dev/docs/s3_params_create.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
163resource_realmкластер S3 для подключенияfunc=getAvailableResourceRealms
320display_namestringЧеловеко-читаемое имя (транслит из Elma) - передаётся имя клиента
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/s3_params_modify.md b/generated/dev/docs/s3_params_modify.md deleted file mode 100644 index d5a1da0..0000000 --- a/generated/dev/docs/s3_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
50max_size_gb_per_userintegermaxSizeGb. Передаём рукамиminvalue=1; maxvalue=50000
51max_objects_per_bucketintegerКвота на бакет. Кол-во объектов. Передаём рукамиminvalue=1; maxvalue=10000000
52max_buckets_per_userintegerКвота на пользователя. Количество бакетов пользователя. Передаём рукамиminvalue=1; maxvalue=1000
diff --git a/generated/dev/docs/s3bucket.md b/generated/dev/docs/s3bucket.md deleted file mode 100644 index 27d17d7..0000000 --- a/generated/dev/docs/s3bucket.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/dev/docs/s3bucket_example.md b/generated/dev/docs/s3bucket_example.md deleted file mode 100644 index a05fdcd..0000000 --- a/generated/dev/docs/s3bucket_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Copy-ready manifest (`s3bucket_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_s3bucket" "baza" { - s3_user_uid = "TODO" # UID Корневой услуги S3. На основе него будет создан бакет. - bucket_name = "TODO" # Имя бакета s3 - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - max_size = -1 # Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes - read_all = false # Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. - list_all = false # Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. - cors_all = false # Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS - placement = "HOT" # Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_s3bucket.baza.state_params["имя_ключа"] -nubes_s3bucket.baza.state_out["имя_ключа"] -nubes_s3bucket.baza.state_params_flat["имя_ключа"] -nubes_s3bucket.baza.state_out_flat["имя_ключа"] -nubes_s3bucket.baza.vault_secrets["имя_ключа"] -nubes_s3bucket.baza.vault_url -nubes_s3bucket.baza.vault_user_path -nubes_s3bucket.baza.vault_fields -``` diff --git a/generated/dev/docs/s3bucket_ops.md b/generated/dev/docs/s3bucket_ops.md deleted file mode 100644 index 61b2abb..0000000 --- a/generated/dev/docs/s3bucket_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](s3bucket_params_create.md) -- `delete` diff --git a/generated/dev/docs/s3bucket_outputs.md b/generated/dev/docs/s3bucket_outputs.md deleted file mode 100644 index f62a754..0000000 --- a/generated/dev/docs/s3bucket_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["httpConnect"]` - diff --git a/generated/dev/docs/s3bucket_params.md b/generated/dev/docs/s3bucket_params.md deleted file mode 100644 index 9977e26..0000000 --- a/generated/dev/docs/s3bucket_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Parameters - -- [Create params](s3bucket_params_create.md) -- [Modify params](s3bucket_params_modify.md) diff --git a/generated/dev/docs/s3bucket_params_create.md b/generated/dev/docs/s3bucket_params_create.md deleted file mode 100644 index 0ae6f44..0000000 --- a/generated/dev/docs/s3bucket_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
124s3_user_uiduuidUID Корневой услуги S3. На основе него будет создан бакет.ref_svc_id=12
125bucket_namestringИмя бакета s3
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
126max_size-1Максимальный размер бакета s3. Если поставить 0, будет безлимит. Размер указывается в Bytes
127read_allbooleanfalseПубличный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета.value_list=false, true
128list_allbooleanfalseПубличный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете.value_list=false, true
129cors_allbooleanfalseПубличный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORSvalue_list=false, true
130placementstringHOTКласс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращенияvalue_list=HOT, COLD
diff --git a/generated/dev/docs/s3bucket_params_modify.md b/generated/dev/docs/s3bucket_params_modify.md deleted file mode 100644 index ca24765..0000000 --- a/generated/dev/docs/s3bucket_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/superset.md b/generated/dev/docs/superset.md deleted file mode 100644 index 93094e9..0000000 --- a/generated/dev/docs/superset.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## MAN - -
-Apache Superset как сервис.
Ресурсная платформа: k8s.
Автоматизация: k8s operator.
Авторизация: 2FA keycloak (для доменного логина @mgmt.nubes.ru) -
diff --git a/generated/dev/docs/superset_example.md b/generated/dev/docs/superset_example.md deleted file mode 100644 index 6abf626..0000000 --- a/generated/dev/docs/superset_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Copy-ready manifest (`superset_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_superset" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - emails = "testuser1" # Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_superset.baza.state_params["имя_ключа"] -nubes_superset.baza.state_out["имя_ключа"] -nubes_superset.baza.state_params_flat["имя_ключа"] -nubes_superset.baza.state_out_flat["имя_ключа"] -nubes_superset.baza.vault_secrets["имя_ключа"] -nubes_superset.baza.vault_url -nubes_superset.baza.vault_user_path -nubes_superset.baza.vault_fields -``` diff --git a/generated/dev/docs/superset_ops.md b/generated/dev/docs/superset_ops.md deleted file mode 100644 index 5aa441d..0000000 --- a/generated/dev/docs/superset_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](superset_params_create.md) -- `delete` — DEV-Ветка удаления Superset diff --git a/generated/dev/docs/superset_outputs.md b/generated/dev/docs/superset_outputs.md deleted file mode 100644 index 4d7a1fd..0000000 --- a/generated/dev/docs/superset_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/superset_params.md b/generated/dev/docs/superset_params.md deleted file mode 100644 index 2984f1c..0000000 --- a/generated/dev/docs/superset_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Parameters - -- [Create params](superset_params_create.md) -- [Modify params](superset_params_modify.md) diff --git a/generated/dev/docs/superset_params_create.md b/generated/dev/docs/superset_params_create.md deleted file mode 100644 index 6652cf1..0000000 --- a/generated/dev/docs/superset_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
109resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
14domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
20emailsstringtestuser1Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел
96resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядроminvalue=100; maxvalue=4000
97resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
98resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
227resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
diff --git a/generated/dev/docs/superset_params_modify.md b/generated/dev/docs/superset_params_modify.md deleted file mode 100644 index 5a6e1ca..0000000 --- a/generated/dev/docs/superset_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/template.md b/generated/dev/docs/template.md deleted file mode 100644 index b4d0dc3..0000000 --- a/generated/dev/docs/template.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/dev/docs/template_example.md b/generated/dev/docs/template_example.md deleted file mode 100644 index 979b7dd..0000000 --- a/generated/dev/docs/template_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Copy-ready manifest (`template_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_template" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 100 - resource_memory = 200 - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_template.baza.state_params["имя_ключа"] -nubes_template.baza.state_out["имя_ключа"] -nubes_template.baza.state_params_flat["имя_ключа"] -nubes_template.baza.state_out_flat["имя_ключа"] -nubes_template.baza.vault_secrets["имя_ключа"] -nubes_template.baza.vault_url -nubes_template.baza.vault_user_path -nubes_template.baza.vault_fields -``` diff --git a/generated/dev/docs/template_ops.md b/generated/dev/docs/template_ops.md deleted file mode 100644 index 7bea1f5..0000000 --- a/generated/dev/docs/template_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](template_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](template_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/template_outputs.md b/generated/dev/docs/template_outputs.md deleted file mode 100644 index ab5623d..0000000 --- a/generated/dev/docs/template_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/template_params.md b/generated/dev/docs/template_params.md deleted file mode 100644 index 7fdd8d3..0000000 --- a/generated/dev/docs/template_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Parameters - -- [Create params](template_params_create.md) -- [Modify params](template_params_modify.md) diff --git a/generated/dev/docs/template_params_create.md b/generated/dev/docs/template_params_create.md deleted file mode 100644 index aaa56ea..0000000 --- a/generated/dev/docs/template_params_create.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
206resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
202resource_cpuinteger100minvalue=100; maxvalue=4000
203resource_memoryinteger200minvalue=128; maxvalue=8192
204resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
205resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
207domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/template_params_modify.md b/generated/dev/docs/template_params_modify.md deleted file mode 100644 index 9e15054..0000000 --- a/generated/dev/docs/template_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
208resource_cpuintegerminvalue=100; maxvalue=4000
209resource_memoryintegerminvalue=128; maxvalue=8192
210resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
211resource_instancesintegerКоличество узловminvalue=1; maxvalue=7
diff --git a/generated/dev/docs/valo_tenant.md b/generated/dev/docs/valo_tenant.md deleted file mode 100644 index 6860e2f..0000000 --- a/generated/dev/docs/valo_tenant.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## MAN - -
-# Инструкция по развертыванию Тенант Valo через платформу

## 1. Общая информация
Тенант Valo — логический изолированный экземпляр сервиса VALO Cloud, предоставляющий защищённое облачное хранилище, синхронизацию данных и доступ к документам с различных устройств. При создании тенант автоматически разворачивается в тестовом режиме сроком на 2 месяца. Перевод в промышленную эксплуатацию выполняется отдельной операцией.

### Доступные операции

* **create** — создание нового тенанта в тестовом режиме сроком на 2 месяца.
* **modify** — изменение настроек тенанта, включая перевод из ТЕСТ в ПРОД.
* **suspend** — выключение (приостановка работы) тенанта.
* **resume** — включение ранее приостановленного тенанта.
* **delete** — удаление тенанта; доступно только после выполнения операции suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создан тенант.
Пример значения: `valo.ngcloud.ru`.

### DNS-Префикс
Описание: Будет добавлено в зону valo.ngcloud.ru
Пример значения: `mysimpledomain`.

### Параметры хранилища
Описание: Сколько места будет выделено под использование в тенанте. Данные хранятся в S3. Размер указывается в Gigabytes
Пример значения: `10`.

### Настройки тенанта
Описание: Ряд конфигурации Valo-тенанта, такие как настройки пользователя и доступного функционала
Пример значения: `опционально в рамках настройки`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
Достаточно развернуть тенант в ТЕСТ. Срок предоставляется в 2 месяца. По истечению срока тенант автоматически переводится в `suspend` на стороне ресурсной платформы

### Промышленное окружение
Для разблокировки используйте операцию `modify`

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Статус тенанта
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация
Тенант всегда создаётся в режиме ТЕСТ и не может быть сразу переведён в ПРОД без операции modify.
Удаление тенанта возможно только после его выключения с помощью операции suspend.
Срок тестового режима составляет 2 месяца с момента создания.
Операции suspend и resume используются для временного управления доступностью сервиса без потери конфигурации.
-
diff --git a/generated/dev/docs/valo_tenant_example.md b/generated/dev/docs/valo_tenant_example.md deleted file mode 100644 index 7f29a47..0000000 --- a/generated/dev/docs/valo_tenant_example.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Copy-ready manifest (`valo_tenant_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_valo_tenant" "baza" { - resource_realm = "TODO" - domain = "TODO" # Будет добавлено в зону valo.ngcloud.ru - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - valo_options = {} - s3_storage = 10 # Параметр указывается в `Gb` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_valo_tenant.baza.state_params["имя_ключа"] -nubes_valo_tenant.baza.state_out["имя_ключа"] -nubes_valo_tenant.baza.state_params_flat["имя_ключа"] -nubes_valo_tenant.baza.state_out_flat["имя_ключа"] -nubes_valo_tenant.baza.vault_secrets["имя_ключа"] -nubes_valo_tenant.baza.vault_url -nubes_valo_tenant.baza.vault_user_path -nubes_valo_tenant.baza.vault_fields -``` diff --git a/generated/dev/docs/valo_tenant_ops.md b/generated/dev/docs/valo_tenant_ops.md deleted file mode 100644 index 89cb168..0000000 --- a/generated/dev/docs/valo_tenant_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](valo_tenant_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](valo_tenant_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/dev/docs/valo_tenant_outputs.md b/generated/dev/docs/valo_tenant_outputs.md deleted file mode 100644 index 2d4ea5d..0000000 --- a/generated/dev/docs/valo_tenant_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/valo_tenant_params.md b/generated/dev/docs/valo_tenant_params.md deleted file mode 100644 index 2c3d14f..0000000 --- a/generated/dev/docs/valo_tenant_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Parameters - -- [Create params](valo_tenant_params_create.md) -- [Modify params](valo_tenant_params_modify.md) diff --git a/generated/dev/docs/valo_tenant_params_create.md b/generated/dev/docs/valo_tenant_params_create.md deleted file mode 100644 index a0e9538..0000000 --- a/generated/dev/docs/valo_tenant_params_create.md +++ /dev/null @@ -1,38 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
655resource_realmstringfunc=getAvailableResourceRealms
656domainstringБудет добавлено в зону valo.ngcloud.ruregex=^[a-z0-9](?:[a-z0-9-]{3,61}[a-z0-9])?$; maxlength=61; minlength=3
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
657valo_optionsmap-fixed{}
658s3_storageinteger10Данные хранятся в отдельном экземпляре S3minvalue=1; maxvalue=999
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/valo_tenant_params_modify.md b/generated/dev/docs/valo_tenant_params_modify.md deleted file mode 100644 index 4b07bec..0000000 --- a/generated/dev/docs/valo_tenant_params_modify.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Modify params - - - - - - -
IDCodeTypeDescriptionConstraints
659valo_optionsmap-fixed
660s3_storageintegerДанные хранятся в отдельном экземпляре S3
diff --git a/generated/dev/docs/vapp.md b/generated/dev/docs/vapp.md deleted file mode 100644 index 630f47c..0000000 --- a/generated/dev/docs/vapp.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## MAN - -
-# Инструкция по развертыванию Виртуальный каталог ВМ (vApp) через платформу

## 1. Общая информация

**Виртуальный каталог ВМ (vApp)** — это логическая каталог, объединённая в единый управляемый объект. Сервис предназначен для совместного развертывания, управления жизненным циклом и сетевого взаимодействия набора связанных ВМ. Основные функции включают:
- централизованное управление включением, выключением и приостановкой группы ВМ;
- унифицированный сетевой доступ через привязанный Edge-шлюз;

### Доступные операции

**create** — Создание нового vApp с привязкой к заданным услугам VDC и Edge
**delete** — Удаление существующего vApp. Требуется предварительный перевод vApp в состояние *suspend*. Полное удаление возможно через 14 дней.
**suspend** — Остановка vApp (выключение всех ВМ внутри каталога)
**resume** — Запуск vApp (включение всех ВМ внутри каталога)

---

## 2. Параметры развертывания

Параметры берутся из операции **create**.

### UUID Услуги VDC
Уникальный идентификатор услуги «Виртуальный датацентр (vDC)».
Используется для определения вычислительной инфраструктуры, в которой будет развернут vApp.

### UUID Услуги Edge
Уникальный идентификатор услуги «Сетевой шлюз периметра (Edge)».
Обеспечивает маршрутизацию и сетевое подключение. Может быть привязан к группе VDC, поэтому выбирается отдельно.

### Имя vApp
Строгое имя, соответствующее маске формирования DNS-имени.
Используется как часть в DNS-имени при создании виртуальных машин.

---

## 3. Рекомендованные характеристики
Так как является промежуточным этапом для создания ВМ, все характеристики описываются в услуге `Виртуальная машина`

---

## 4. Выходные параметры

### Параметры vApp
Заданные при создании vApp

---

## 5. Дополнительная информация

- Привязка к VDC и Edge осуществляется раздельно, поскольку один Edge может обслуживать несколько VDC (через услугу `Группа виртуальных датацентров (groupvDC)`). Это гарантирует возможность развернуть ВМ в единой сети, но в разных виртуальных датацентрах.
- Перед удалением vApp необходимо вручную перевести его в состояние **suspend**. Удаление возможно только спустя 14 дней после этого шага.
- Операция delete удаляет весь vApp полностью, включая все виртуальные машины, связанные с ним.
- Рекомендуется заранее планировать сетевые связи и назначения DNS-имён для обеспечения корректной работы сервисов, развернутых внутри vApp.
- При проектировании инфраструктуры следует учитывать зависимости между Edge-шлюзом, VDC и размещаемыми ВМ, чтобы избежать ограничений при масштабировании и интеграции. -
diff --git a/generated/dev/docs/vapp_example.md b/generated/dev/docs/vapp_example.md deleted file mode 100644 index cd9335b..0000000 --- a/generated/dev/docs/vapp_example.md +++ /dev/null @@ -1,45 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Copy-ready manifest (`vapp_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vapp" "baza" { - nsxt_uid = "TODO" # UUID Услуги `Сетевой шлюз периметра (Edge)` - vapp_name = "TODO" # Уникальное в рамках организации - vdc_uid = "TODO" # UUID Услуги `Виртуальный датацентр (vDC)` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vapp.baza.state_params["имя_ключа"] -nubes_vapp.baza.state_out["имя_ключа"] -nubes_vapp.baza.state_params_flat["имя_ключа"] -nubes_vapp.baza.state_out_flat["имя_ключа"] -nubes_vapp.baza.vault_secrets["имя_ключа"] -nubes_vapp.baza.vault_url -nubes_vapp.baza.vault_user_path -nubes_vapp.baza.vault_fields -``` diff --git a/generated/dev/docs/vapp_ops.md b/generated/dev/docs/vapp_ops.md deleted file mode 100644 index 5e1eba0..0000000 --- a/generated/dev/docs/vapp_ops.md +++ /dev/null @@ -1,14 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vapp_params_create.md) -- `delete` -- `resume` -- `suspend` diff --git a/generated/dev/docs/vapp_outputs.md b/generated/dev/docs/vapp_outputs.md deleted file mode 100644 index 0ff0f8e..0000000 --- a/generated/dev/docs/vapp_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/vapp_params.md b/generated/dev/docs/vapp_params.md deleted file mode 100644 index 4c7addc..0000000 --- a/generated/dev/docs/vapp_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Parameters - -- [Create params](vapp_params_create.md) -- [Modify params](vapp_params_modify.md) diff --git a/generated/dev/docs/vapp_params_create.md b/generated/dev/docs/vapp_params_create.md deleted file mode 100644 index 3b23cff..0000000 --- a/generated/dev/docs/vapp_params_create.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
190nsxt_uiduuidК какой сети может быть подключен виртуальный каталогref_svc_id=22
191vapp_namestringИмеет строгую маску `^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$`

Используется в формировании DNS-Имени (для виртуальных машин)
regex=^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$; minlength=3
623vdc_uiduuidВ каких ресурсах будет создан виртуальный каталогref_svc_id=21
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/vapp_params_modify.md b/generated/dev/docs/vapp_params_modify.md deleted file mode 100644 index 4fca747..0000000 --- a/generated/dev/docs/vapp_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/vc_nsxt.md b/generated/dev/docs/vc_nsxt.md deleted file mode 100644 index 0c8056d..0000000 --- a/generated/dev/docs/vc_nsxt.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## MAN - -
-# Инструкция по развертыванию Сетевой шлюз периметра (Edge) через платформу

## 1. Общая информация

Сервис **Сетевой шлюз периметра (Edge)** предназначен для создания периметрового сетевого шлюза в рамках одного виртуального датацентра (vDC) или группы виртуальных датацентров (groupvDC).
При создании автоматически разворачивается routed-сеть с адресным пространством `10.10.102.0/24`.
Сервис обеспечивает сетевую изоляцию, маршрутизацию, а также может включать функциональность балансировщика нагрузки AVI (ALB) для последующей интеграции, включая поддержку кластеров Штурвал.

### Доступные операции

**create** — Создание нового Edge с привязкой к vDC или groupvDC и развёртыванием routed-сети.
**delete** — Удаление ранее созданного Edge. Недоступно при наличии зависимых услуг (vApp, VM, Кластер Штурвал).
**modify** — Изменение параметров и сетевых настроек существующего Edge.

---

## 2. Параметры развертывания

Ниже приведены параметры операции **create**.

### Тип родительской услуги
Определяет контекст размещения Edge.
Допустимые значения: `vdc`, `groupvdc`.
Использование:
- При выборе `vdc` обязателен параметр **UUID VDC**.
- При выборе `groupvdc` обязателен параметр **UUID Группы VDC**.

### UUID VDC
Идентификатор виртуального датацентра.
Необходимо предварительно создать vDC через услугу «Виртуальный датацентр (vDC)».
Указывается только при выборе родительского типа `vdc`.

### UUID Группы VDC
Идентификатор группы виртуальных датацентров.
Создаётся через услугу «Группа виртуальных датацентров (groupvDC)».
Используется при выборе родительского типа `groupvdc`.

### Включить ALB
Флаг активации AVI Load Balancer в Cloud Director.
Пример значения: `true`/`false`.
Нужен для развёртывания кластера Штурвал и возможности создания Virtual Services.

### Наименование segroup
Имя сервиса групп (segroup) на уровне ресурсной платформы.
Обязательно при включённом ALB.
Определяет группу, в которой будут выделяться пулы AVI для Virtual Services.

### virtualServicesCount
Количество резервируемых виртуальных сервисов (Virtual Services) на AVI.
Типичное значение: 1–10 в зависимости от нагрузки.

---

## 3. Рекомендованные характеристики

### Тестовое окружение (Test)

- Тип родительской услуги: `vdc`
- virtualServicesCount: 1–2
- ALB: выключен по умолчанию (включать только при необходимости тестирования Штурвала)
- segroup: задаётся только при включённом ALB
- VDC гарантии CPU/RAM: минимальные (поскольку изменить их после создания нельзя)

### Промышленное окружение (Production)

- Тип родительской услуги: `groupvdc` при работе с распределёнными нагрузками или `vdc` для локализованных проектов
- virtualServicesCount: 3–10, исходя из предполагаемого количества публикаций
- ALB: включён, если требуется высокая доступность сервисов или используется кластер Штурвал
- segroup: рекомендуется использовать выделенную группу под проект
- VDC гарантии CPU/RAM: повышенные, с учётом того, что изменить их после создания невозможно без пересоздания vDC

---

## 4. Выходные параметры

### Имя Edge
Уникальное название созданного сетевого шлюза, используется для ссылок и дальнейших операций.

### Имя routed-сети
Автоматически созданная routed-сеть с подсетью `10.10.102.0/24`, используется для подключения ресурсов.

### Параметры Edge
Набор параметров, указанных пользователем при создании: тип услуги, ALB, segroup, virtualServicesCount и др.
Используются в операциях modify и для анализа состояния сервиса.

---

## 5. Дополнительная информация

- В рамках сервиса **один раз при создании задаётся гарантированная доля CPU/RAM vDC**. Изменить её невозможно — требуется пересоздание vDC.
- Удаление Edge недоступно при наличии зависимых ресурсов (vApp, VM, кластер Штурвал).
- При использовании ALB необходимо корректно указывать segroup, чтобы обеспечить корректное выделение пулов AVI.
- При выборе режима `groupvdc` следует учитывать распределение нагрузки между несколькими vDC.
- SNAT для всех ресурсов внутри Edge можно активировать через операцию modify (параметры выделения VIP и ipSpace).

-
diff --git a/generated/dev/docs/vc_nsxt_example.md b/generated/dev/docs/vc_nsxt_example.md deleted file mode 100644 index 7c5d4c4..0000000 --- a/generated/dev/docs/vc_nsxt_example.md +++ /dev/null @@ -1,47 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Copy-ready manifest (`vc_nsxt_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_nsxt" "baza" { - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - need_enable_avi = false # Включение Load Balancer - virtual_services_count = 1 # Кол-во виртуальных сервисов, которые **резервируются** на AVI - vdc_type = "vdc" # Тип родительской услуги -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_nsxt.baza.state_params["имя_ключа"] -nubes_vc_nsxt.baza.state_out["имя_ключа"] -nubes_vc_nsxt.baza.state_params_flat["имя_ключа"] -nubes_vc_nsxt.baza.state_out_flat["имя_ключа"] -nubes_vc_nsxt.baza.vault_secrets["имя_ключа"] -nubes_vc_nsxt.baza.vault_url -nubes_vc_nsxt.baza.vault_user_path -nubes_vc_nsxt.baza.vault_fields -``` diff --git a/generated/dev/docs/vc_nsxt_ops.md b/generated/dev/docs/vc_nsxt_ops.md deleted file mode 100644 index 03af84f..0000000 --- a/generated/dev/docs/vc_nsxt_ops.md +++ /dev/null @@ -1,14 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_nsxt_params_create.md) -- `delete` — Невозможно удалить если routed-сеть в Edge связана с: - vApp - VM - Kubernetes-кластер Штурвал Запустить операцию возможно, но будет ошибка -- `modify` — Изменение кластера. Параметры: [Modify params](vc_nsxt_params_modify.md) -- `reconcile` diff --git a/generated/dev/docs/vc_nsxt_outputs.md b/generated/dev/docs/vc_nsxt_outputs.md deleted file mode 100644 index 717cbc4..0000000 --- a/generated/dev/docs/vc_nsxt_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/vc_nsxt_params.md b/generated/dev/docs/vc_nsxt_params.md deleted file mode 100644 index 2cf1cc1..0000000 --- a/generated/dev/docs/vc_nsxt_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Parameters - -- [Create params](vc_nsxt_params_create.md) -- [Modify params](vc_nsxt_params_modify.md) diff --git a/generated/dev/docs/vc_nsxt_params_create.md b/generated/dev/docs/vc_nsxt_params_create.md deleted file mode 100644 index 9f77ac0..0000000 --- a/generated/dev/docs/vc_nsxt_params_create.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
8vdc_uidstringНеобходимо, если выбран тип подключаемой VDC: `vdc`ref_svc_id=21
622vdc_group_uidstringНеобходимо, если выбран тип подключаемой VDC: `groupvdc`ref_svc_id=29
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
340need_enable_avibooleanfalseПараметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указатьvalue_list=false, true
341virtual_services_countinteger1Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB`
minvalue=1; maxvalue=4
621vdc_typestringvdcПри выборе vdc обеспечивает сетевую доступность только в рамках этого vdc
При выборе groupvdc обеспечивает сетевую доступность между всеми vdc, которые включены в groupvdc
value_list=vdc, vdcGroup
diff --git a/generated/dev/docs/vc_nsxt_params_modify.md b/generated/dev/docs/vc_nsxt_params_modify.md deleted file mode 100644 index 0a1fc0e..0000000 --- a/generated/dev/docs/vc_nsxt_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
368need_enable_avibooleanПараметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указатьvalue_list=false, true
369virtual_services_countintegerВо избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB`
minvalue=1; maxvalue=4
371need_external_address_snatbooleanПараметр `ip Space для VIP` станет обязательным, если указан `true`value_list=false, true
372ip_space_namestringНеобходимо указывать, если включён параметр `Выделить VIP для SNAT`
diff --git a/generated/dev/docs/vc_org.md b/generated/dev/docs/vc_org.md deleted file mode 100644 index e500201..0000000 --- a/generated/dev/docs/vc_org.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## MAN - -
-# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Url организации
Для быстрого доступа в тенант

### Статус организации
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)** привязанный к этой организации;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к vdc выше.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak. -
diff --git a/generated/dev/docs/vc_org_example.md b/generated/dev/docs/vc_org_example.md deleted file mode 100644 index c6e548e..0000000 --- a/generated/dev/docs/vc_org_example.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Copy-ready manifest (`vc_org_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_org" "baza" { - resource_realm = "TODO" # Облако в котором будет развёрнут тенант - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - organization_type = "iaas" # Доступ к организации предоставляется только при выборе `iaas` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_org.baza.state_params["имя_ключа"] -nubes_vc_org.baza.state_out["имя_ключа"] -nubes_vc_org.baza.state_params_flat["имя_ключа"] -nubes_vc_org.baza.state_out_flat["имя_ключа"] -nubes_vc_org.baza.vault_secrets["имя_ключа"] -nubes_vc_org.baza.vault_url -nubes_vc_org.baza.vault_user_path -nubes_vc_org.baza.vault_fields -``` diff --git a/generated/dev/docs/vc_org_ops.md b/generated/dev/docs/vc_org_ops.md deleted file mode 100644 index a0c2067..0000000 --- a/generated/dev/docs/vc_org_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_org_params_create.md) -- `delete` — Удалить возможно только через 14 дней после выполнения операции `suspend` **ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого тенанта** Если существуют инстансы VDC, Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов -- `modify` — Изменение кластера. Параметры: [Modify params](vc_org_params_modify.md) -- `reconcile` -- `resume` -- `suspend` — Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри тенанта diff --git a/generated/dev/docs/vc_org_outputs.md b/generated/dev/docs/vc_org_outputs.md deleted file mode 100644 index 9de11b9..0000000 --- a/generated/dev/docs/vc_org_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["urlConnect"]` - diff --git a/generated/dev/docs/vc_org_params.md b/generated/dev/docs/vc_org_params.md deleted file mode 100644 index e187b07..0000000 --- a/generated/dev/docs/vc_org_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Parameters - -- [Create params](vc_org_params_create.md) -- [Modify params](vc_org_params_modify.md) diff --git a/generated/dev/docs/vc_org_params_create.md b/generated/dev/docs/vc_org_params_create.md deleted file mode 100644 index 28f12f0..0000000 --- a/generated/dev/docs/vc_org_params_create.md +++ /dev/null @@ -1,36 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
418resource_realmstringВыбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы
func=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
556organization_typestringiaasДоступ к организации предоставляется только при выборе `iaas`value_list=iaas, saas
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/vc_org_params_modify.md b/generated/dev/docs/vc_org_params_modify.md deleted file mode 100644 index 4142f72..0000000 --- a/generated/dev/docs/vc_org_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
662v_ipconfigurearray-map-fixed
diff --git a/generated/dev/docs/vc_vdc.md b/generated/dev/docs/vc_vdc.md deleted file mode 100644 index 2d8fa57..0000000 --- a/generated/dev/docs/vc_vdc.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## MAN - -
-# Инструкция по развертыванию Виртуальный датацентр (vDC) через платформу

## 1. Общая информация

**Виртуальный датацентр (vDC)** — это логическая изолированная среда в VMware Cloud Director, предназначенная для размещения и управления виртуальными машинами, сетевой инфраструктурой и ресурсами хранения. Сервис обеспечивает выделение вычислительных ресурсов под конкретную организацию и предоставляет гибкие параметры масштабирования, контроля потребления и разделения ресурсов.

### Доступные операции

**create** — Создание виртуального датацентра (vDC) с заданными параметрами CPU, RAM, Storage и сетевой конфигурацией.
**delete** — Удаление vDC. Требуется предварительный перевод vDC в состояние *suspend*. Полное удаление возможно через 14 дней.
**modify** — Внесение изменений в параметры ресурсов (CPU/RAM/Storage), выделенных для vDC.
**suspend** — Заморозка vDC. Новые ресурсы или изменения внутри vDC становятся невозможными, работа ВМ не останавливается.
**resume** — Разморозка vDC. Восстановление возможности управления сущностями внутри vDC.

---

## 2. Параметры развертывания

Ниже перечислены входные параметры операции **create**.

### UUID Организации
Уникальный идентификатор организации в Cloud Director. Перед созданием vDC требуется предварительное создание услугу `Организация в Cloud Director`.

### Provider VDC в Cloud Director
Свойство ресурсной платформы, определяющее, какой пул физических ресурсов будет использоваться.

### Network Pool в Cloud Director
Определяет возможности сетевой конфигурации, включая создание Edge Gateway и выход во внешние сети.

### Гарантированная доля ЯДЕР
Гарантированный процент вычислительных ресурсов (CPU), закрепленный за vDC. Значение устанавливается разово при создании.

### Гарантированная доля ОЗУ
Гарантированный процент оперативной памяти, закрепленный за vDC. Также задаётся один раз при создании.

### Сколько аллоцировать на VDC ЯДЕР
Количество виртуальных ядер, выделяемых в рамках vDC.

### Сколько аллоцировать на VDC ОЗУ
Количество оперативной памяти в GB, выделяемой для vDC.

### Конфигурация Storage
Набор дисковых политик и их объёмов, выделяемых для vDC. Указывается имя политики и требуемый размер (GB).

---

## 3. Рекомендованные характеристики

### Тестовое окружение

- Количество ядер CPU: 10–20
- Аллоцируемая RAM: 16–64 GB
- Гарантированная доля CPU: 20%
- Гарантированная доля RAM: 20%
- Storage:
- Политика `SATA`
- Объём: 100–300 GB

### Промышленное окружение

- Количество ядер CPU: 16–128
- Аллоцируемая RAM: 64–512 GB
- Гарантированная доля CPU: 50%
- Гарантированная доля RAM: 50%
- Storage:
- Политики уровня `SSD`
- Объём: 1–10 TB, выбор несколько политик под разные нагрузки

---

## 4. Выходные параметры

Выходные параметры формируются операцией **create** (и используются другими операциями):

### Имя vDC
Уникальный идентификатор созданного виртуального датацентра. Используется в дальнейших операциях (modify, suspend, delete).

### Параметры выделенных ресурсов
Подтверждение итогового объёма CPU/RAM/Storage, выделенных vDC. Используются для учёта и контроля потребления.

---

## 5. Дополнительная информация

- Перед созданием vDC необходимо обеспечить наличие корректно созданной организации и доступных пула ресурсов ресурсной платформы.
- Гарантированная доля CPU и RAM задаётся **однократно при создании vDC**. После развертывания изменить эти значения невозможно; для изменения необходимо пересоздать vDC.
- Удаление vDC возможно только через **14 дней после перевода в состояние *suspend***. Удаление очищает все связанные сущности (ВМ, сети, каталоги), поэтому необходимо убедиться, что данные перенесены.
- Платформа Cloud Director использует концепцию изолированных организационных ресурсов, поэтому корректная настройка Provider VDC и Network Pool является обязательной при создании vDC.
- При изменении параметров (modify) изменяются только показатели CPU, RAM и Storage. Сетевые параметры и гарантированные доли остаются неизменными.
-
diff --git a/generated/dev/docs/vc_vdc_example.md b/generated/dev/docs/vc_vdc_example.md deleted file mode 100644 index 0933efa..0000000 --- a/generated/dev/docs/vc_vdc_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Copy-ready manifest (`vc_vdc_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_vdc" "baza" { - organization_uid = "TODO" # Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` - provider_vdc = "TODO" # Приписка `2.8` - Скорость vCPU - 2800MHz И так далее... - network_provider = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - storage_config = [{}] # Первая политика в списке указывается как "По умолчанию" - cpu_guaranteed = 20 # % резервирования - cpu_allocated = 10 # шт - mem_allocated = 20 # gb -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vdc.baza.state_params["имя_ключа"] -nubes_vc_vdc.baza.state_out["имя_ключа"] -nubes_vc_vdc.baza.state_params_flat["имя_ключа"] -nubes_vc_vdc.baza.state_out_flat["имя_ключа"] -nubes_vc_vdc.baza.vault_secrets["имя_ключа"] -nubes_vc_vdc.baza.vault_url -nubes_vc_vdc.baza.vault_user_path -nubes_vc_vdc.baza.vault_fields -``` diff --git a/generated/dev/docs/vc_vdc_group.md b/generated/dev/docs/vc_vdc_group.md deleted file mode 100644 index 1ff3cd6..0000000 --- a/generated/dev/docs/vc_vdc_group.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## MAN - -
-# Инструкция по развертыванию Группа виртуальных датацентров (groupvDC) через платформу

## 1. Общая информация

Сервис **Группа виртуальных датацентров (groupvDC)** предназначен для логического объединения нескольких виртуальных датацентров (vDC) в единую группу. Это позволяет растягивать SDN между разными vDC и централизованно управлять сетевой связностью. Управление инфраструктурой осуществляется через Cloud Director.
Сервис применяется в случаях, когда требуется обеспечить единое сетевое пространство для распределенных виртуальных датацентров.

### Доступные операции

**create** — Создание новой группы виртуальных датацентров.
**delete** — Удаление существующей группы vDC.
**add_vdc** — Добавление дополнительного виртуального датацентра в группу.
**remove_vdc** — Удаление ранее добавленного виртуального датацентра из группы.

---

## 2. Параметры развертывания

Параметры операции **create**:

### UUID VDC
Идентификатор виртуального датацентра, который будет являться первичным в группе.
Описание: требуется предварительно создать виртуальный датацентр с помощью услуги `Виртуальный датацентр (vDC)`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Для тестового окружения создавать группу VDC нет необходимости, так как это создаёт дополнительный слой абстракции в Cloud Director

### Промышленное окружение
- Для промышленного окружения, если в тенанте существуют разные VDC, создание groupvdc позволит снизить сетевые издержки (за счёт общей сети)

---

## 4. Выходные параметры

### Параметры groupvdc
Набор параметров, указанных пользователем при создании

---

## 5. Дополнительная информация
- Группа vDC используется для растягивания SDN между несколькими виртуальными датацентрами. Управление всеми сетевыми элементами внутри группы выполняется Cloud Director.
- Удалить первичный vDC (тот, что был указан при операции **create**) невозможно. Для его удаления необходимо удалить всю группу и создать новую.
- Перед добавлением любого vDC в группу он должен быть предварительно развернут через сервис `Виртуальный датацентр (vDC)`.
- Сети создаются не в этой услуге, а в услуге `Сетевой шлюз периметра (Edge)`. В ней необходимо будет выбрать тип `groupvdc` -
diff --git a/generated/dev/docs/vc_vdc_group_example.md b/generated/dev/docs/vc_vdc_group_example.md deleted file mode 100644 index a2f1480..0000000 --- a/generated/dev/docs/vc_vdc_group_example.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Copy-ready manifest (`vc_vdc_group_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_vdc_group" "baza" { - vdc_uid = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vdc_group.baza.state_params["имя_ключа"] -nubes_vc_vdc_group.baza.state_out["имя_ключа"] -nubes_vc_vdc_group.baza.state_params_flat["имя_ключа"] -nubes_vc_vdc_group.baza.state_out_flat["имя_ключа"] -nubes_vc_vdc_group.baza.vault_secrets["имя_ключа"] -nubes_vc_vdc_group.baza.vault_url -nubes_vc_vdc_group.baza.vault_user_path -nubes_vc_vdc_group.baza.vault_fields -``` diff --git a/generated/dev/docs/vc_vdc_group_ops.md b/generated/dev/docs/vc_vdc_group_ops.md deleted file mode 100644 index 9552c15..0000000 --- a/generated/dev/docs/vc_vdc_group_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Operations - -- `add_vdc` — **Не нужно** выбирать UUID VDC, который уже был добавлен в группу -- `create` — Создание кластера. Параметры: [Create params](vc_vdc_group_params_create.md) -- `delete` -- `reconcile` -- `remove_vdc` diff --git a/generated/dev/docs/vc_vdc_group_outputs.md b/generated/dev/docs/vc_vdc_group_outputs.md deleted file mode 100644 index 5714cde..0000000 --- a/generated/dev/docs/vc_vdc_group_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/vc_vdc_group_params.md b/generated/dev/docs/vc_vdc_group_params.md deleted file mode 100644 index d292ab9..0000000 --- a/generated/dev/docs/vc_vdc_group_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Parameters - -- [Create params](vc_vdc_group_params_create.md) -- [Modify params](vc_vdc_group_params_modify.md) diff --git a/generated/dev/docs/vc_vdc_group_params_create.md b/generated/dev/docs/vc_vdc_group_params_create.md deleted file mode 100644 index 624e982..0000000 --- a/generated/dev/docs/vc_vdc_group_params_create.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
618vdc_uiduuidref_svc_id=21
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/dev/docs/vc_vdc_group_params_modify.md b/generated/dev/docs/vc_vdc_group_params_modify.md deleted file mode 100644 index 721de57..0000000 --- a/generated/dev/docs/vc_vdc_group_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Modify params - -None. diff --git a/generated/dev/docs/vc_vdc_ops.md b/generated/dev/docs/vc_vdc_ops.md deleted file mode 100644 index b1a1776..0000000 --- a/generated/dev/docs/vc_vdc_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vdc_params_create.md) -- `delete` — Удалить возможно только через 14 дней после выполнения операции `suspend` **ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого VDC** Если существуют инстансы Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vdc_params_modify.md) -- `reconcile` -- `resume` -- `suspend` — Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри VDC diff --git a/generated/dev/docs/vc_vdc_outputs.md b/generated/dev/docs/vc_vdc_outputs.md deleted file mode 100644 index a435292..0000000 --- a/generated/dev/docs/vc_vdc_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["vdcName"]` - diff --git a/generated/dev/docs/vc_vdc_params.md b/generated/dev/docs/vc_vdc_params.md deleted file mode 100644 index 03c0037..0000000 --- a/generated/dev/docs/vc_vdc_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Parameters - -- [Create params](vc_vdc_params_create.md) -- [Modify params](vc_vdc_params_modify.md) diff --git a/generated/dev/docs/vc_vdc_params_create.md b/generated/dev/docs/vc_vdc_params_create.md deleted file mode 100644 index 01bc413..0000000 --- a/generated/dev/docs/vc_vdc_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
30organization_uiduuidДля создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director`ref_svc_id=19
335provider_vdcstringПриписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
746network_providerstring
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
361storage_configarray-map-fixed[{}]Первая политика в списке указывается как &quot;По умолчанию&quot;
397cpu_guaranteedinteger20Свойство нельзя изменить после созданияvalue_list=20, 50, 80
557cpu_allocatedinteger10штminvalue=1; maxvalue=200
558mem_allocatedinteger20gbminvalue=1; maxvalue=4096
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/vc_vdc_params_modify.md b/generated/dev/docs/vc_vdc_params_modify.md deleted file mode 100644 index 4bb0906..0000000 --- a/generated/dev/docs/vc_vdc_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
560cpu_allocatedintegerштminvalue=1; maxvalue=999
561mem_allocatedintegergbminvalue=1; maxvalue=1024
562storage_configarray-map-fixedПервая политика в списке указывается как &quot;По умолчанию&quot;
diff --git a/generated/dev/docs/vc_vm_v3.md b/generated/dev/docs/vc_vm_v3.md deleted file mode 100644 index 95856d8..0000000 --- a/generated/dev/docs/vc_vm_v3.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## MAN - -
-# Документация по разворачиванию ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\ложь, определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed" (В нем не будет работать сбор метрик zabbix).

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики -
diff --git a/generated/dev/docs/vc_vm_v3_example.md b/generated/dev/docs/vc_vm_v3_example.md deleted file mode 100644 index e6d39ac..0000000 --- a/generated/dev/docs/vc_vm_v3_example.md +++ /dev/null @@ -1,53 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Copy-ready manifest (`vc_vm_v3_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_vm_v3" "baza" { - vapp_uid = "TODO" - ip_space_name = "TODO" - image_vm = "TODO" - user_public_key = "TODO" # Публичная часть SSH-Ключа для пользователя - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - vm_name = "web01" - vm_cpu = 1 # шт - vm_ram = 1 # Gb - user_login = "myuser" # Учётка SSH - access_port_list = ["22"] # По каким портам открыть доступ к ВМ. Порты 22, 10050 проставляются автоматически Пока доступно: 22 - SSH, 80 - HTTP, 443 - HTTPS, 10050 - ZABBIX -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vm_v3.baza.state_params["имя_ключа"] -nubes_vc_vm_v3.baza.state_out["имя_ключа"] -nubes_vc_vm_v3.baza.state_params_flat["имя_ключа"] -nubes_vc_vm_v3.baza.state_out_flat["имя_ключа"] -nubes_vc_vm_v3.baza.vault_secrets["имя_ключа"] -nubes_vc_vm_v3.baza.vault_url -nubes_vc_vm_v3.baza.vault_user_path -nubes_vc_vm_v3.baza.vault_fields -``` diff --git a/generated/dev/docs/vc_vm_v3_ops.md b/generated/dev/docs/vc_vm_v3_ops.md deleted file mode 100644 index 29b88fb..0000000 --- a/generated/dev/docs/vc_vm_v3_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vm_v3_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vm_v3_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/dev/docs/vc_vm_v3_outputs.md b/generated/dev/docs/vc_vm_v3_outputs.md deleted file mode 100644 index d0ef2e1..0000000 --- a/generated/dev/docs/vc_vm_v3_outputs.md +++ /dev/null @@ -1,30 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["fqdn"]` -- `state_out_flat["internalConnect"]` - diff --git a/generated/dev/docs/vc_vm_v3_params.md b/generated/dev/docs/vc_vm_v3_params.md deleted file mode 100644 index 9c63ad1..0000000 --- a/generated/dev/docs/vc_vm_v3_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Parameters - -- [Create params](vc_vm_v3_params_create.md) -- [Modify params](vc_vm_v3_params_modify.md) diff --git a/generated/dev/docs/vc_vm_v3_params_create.md b/generated/dev/docs/vc_vm_v3_params_create.md deleted file mode 100644 index aff77f9..0000000 --- a/generated/dev/docs/vc_vm_v3_params_create.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
407vapp_uiduuidref_svc_id=26
411vm_diskintegerОсновной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму
regex=^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$
412ip_space_namestring
413access_ip_listjsonФормат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено [&quot;0.0.0.0/0&quot;]
regex=^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$
414image_vmstring
415cloud_inityamlМожно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов.
417user_public_keystringПубличная часть SSH-Ключа для пользователя
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
408vm_namestringweb01regex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
409vm_cpuinteger1штminvalue=1; maxvalue=64
410vm_raminteger1Gbminvalue=1; maxvalue=256
416user_loginmyuserУчётка SSH
448access_port_liststring["22"]По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/dev/docs/vc_vm_v3_params_modify.md b/generated/dev/docs/vc_vm_v3_params_modify.md deleted file mode 100644 index e993928..0000000 --- a/generated/dev/docs/vc_vm_v3_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
493vm_cpuintegerштminvalue=1; maxvalue=64
494vm_ramintegerGbminvalue=1; maxvalue=256
495vm_diskintegerОсновной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму
regex=^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$
496ip_space_namestringno-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev
value_list=no-needed, internet-antiddos-v1, internet-no-antiddos-v1, internet-ipv4-v1
497access_ip_listjsonФормат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено [&quot;0.0.0.0/0&quot;]
498access_port_listjsonФормат массива
По каким портам открыть доступ к ВМ.
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX
diff --git a/generated/dev/docs/vcexternalip.md b/generated/dev/docs/vcexternalip.md deleted file mode 100644 index 3fe625c..0000000 --- a/generated/dev/docs/vcexternalip.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## MAN - -
-**Обычно эта услуга разворачивается автоматически при развёртывании более сложных услуг**
Вручную создавать можно, однако услуга требует много параметров, о которых можно просто не знать

Резервировать публичные IP адреса можно только после создания NGcloud Organization, NGcloud Виртуальный датацентр, NGcloud Каталог, Сетевой шлюз периметра.
Вы можете назначить IP адрес для существующего экземпляра сервиса. -
diff --git a/generated/dev/docs/vcexternalip_example.md b/generated/dev/docs/vcexternalip_example.md deleted file mode 100644 index fbdb48b..0000000 --- a/generated/dev/docs/vcexternalip_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Copy-ready manifest (`vcexternalip_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vcexternalip" "baza" { - service_uid = "TODO" - internal_addr_access = "TODO" # Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true - from_service_namespace = "TODO" # Namespace составной услуги (для отображения правил FW) - ip_space_name = "TODO" # Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1) - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - dnat_create = true # Необходимо создать DNAT-правило. - internal_port_access = 5432 # Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vcexternalip.baza.state_params["имя_ключа"] -nubes_vcexternalip.baza.state_out["имя_ключа"] -nubes_vcexternalip.baza.state_params_flat["имя_ключа"] -nubes_vcexternalip.baza.state_out_flat["имя_ключа"] -nubes_vcexternalip.baza.vault_secrets["имя_ключа"] -nubes_vcexternalip.baza.vault_url -nubes_vcexternalip.baza.vault_user_path -nubes_vcexternalip.baza.vault_fields -``` diff --git a/generated/dev/docs/vcexternalip_ops.md b/generated/dev/docs/vcexternalip_ops.md deleted file mode 100644 index 5668481..0000000 --- a/generated/dev/docs/vcexternalip_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vcexternalip_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vcexternalip_params_modify.md) diff --git a/generated/dev/docs/vcexternalip_outputs.md b/generated/dev/docs/vcexternalip_outputs.md deleted file mode 100644 index aaa59e1..0000000 --- a/generated/dev/docs/vcexternalip_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalIp"]` - diff --git a/generated/dev/docs/vcexternalip_params.md b/generated/dev/docs/vcexternalip_params.md deleted file mode 100644 index 1db2fcc..0000000 --- a/generated/dev/docs/vcexternalip_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Parameters - -- [Create params](vcexternalip_params_create.md) -- [Modify params](vcexternalip_params_modify.md) diff --git a/generated/dev/docs/vcexternalip_params_create.md b/generated/dev/docs/vcexternalip_params_create.md deleted file mode 100644 index 995a3b8..0000000 --- a/generated/dev/docs/vcexternalip_params_create.md +++ /dev/null @@ -1,36 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
140service_uidstring
143snat_createbooleanНеобходимо создать SNAT-правило.
144internal_addr_accessstringВнутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true
324from_service_namespacestringNamespace составной услуги (для отображения правил FW)
325from_service_cloud_edge_namestringEdge составной услуги (указывать, если resourceRealm связан с CloudDirector)
326from_service_cloud_vdc_nameVdc составной услуги (указывать, если resourceRealm связан с CloudDirector)
327from_service_cloud_org_namestringOrg составной услуги (указывать, если resourceRealm связан с CloudDirector)
328from_service_cloud_vmware_urlstringApi-Url составной услуги (указывать, если resourceRealm связан с CloudDirector)
336ip_space_namestringТип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1)
488resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
624from_service_cloud_edge_scopestring
626from_service_vdc_group_namestring
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
141dnat_createbooleantrueНеобходимо создать DNAT-правило.
142internal_port_accessstring5432Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
diff --git a/generated/dev/docs/vcexternalip_params_modify.md b/generated/dev/docs/vcexternalip_params_modify.md deleted file mode 100644 index f17b66c..0000000 --- a/generated/dev/docs/vcexternalip_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
627service_uidstring
628ip_space_namestring
629dnat_createboolean
630snat_createboolean
631internal_port_accessstring
632internal_addr_accessstring
diff --git a/generated/dev/docs/zones_v2.md b/generated/dev/docs/zones_v2.md deleted file mode 100644 index 187c13e..0000000 --- a/generated/dev/docs/zones_v2.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_zones_v2 - -Service ID: `109` - -Service Name: Управление днс-зонами и записями - -[Manual](zones_v2.md) | [Create params](zones_v2_params_create.md) | [Modify params](zones_v2_params_modify.md) | [Output params](zones_v2_outputs.md) | [Operations](zones_v2_ops.md) | [Example](zones_v2_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/dev/docs/zones_v2_example.md b/generated/dev/docs/zones_v2_example.md deleted file mode 100644 index 4d130a4..0000000 --- a/generated/dev/docs/zones_v2_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_zones_v2 - -Service ID: `109` - -Service Name: Управление днс-зонами и записями - -[Manual](zones_v2.md) | [Create params](zones_v2_params_create.md) | [Modify params](zones_v2_params_modify.md) | [Output params](zones_v2_outputs.md) | [Operations](zones_v2_ops.md) | [Example](zones_v2_example.md) - -## Copy-ready manifest (`zones_v2_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.39" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_zones_v2" "baza" { - zone_name = "TODO" # Имя зоны - resource_realm = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - zone_kind = "NATIVE" # Тип зоны - zone_time_to_refresh = 86400 # Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов - zone_time_to_retry = 7200 # Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов - zone_time_to_expire = 3600000 # Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным - zone_time_to_live = 86400 # Время, в течение которого информация будет кешироваться другими DNS-серверами -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_zones_v2.baza.state_params["имя_ключа"] -nubes_zones_v2.baza.state_out["имя_ключа"] -nubes_zones_v2.baza.state_params_flat["имя_ключа"] -nubes_zones_v2.baza.state_out_flat["имя_ключа"] -nubes_zones_v2.baza.vault_secrets["имя_ключа"] -nubes_zones_v2.baza.vault_url -nubes_zones_v2.baza.vault_user_path -nubes_zones_v2.baza.vault_fields -``` diff --git a/generated/dev/docs/zones_v2_ops.md b/generated/dev/docs/zones_v2_ops.md deleted file mode 100644 index dd3e0ab..0000000 --- a/generated/dev/docs/zones_v2_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_zones_v2 - -Service ID: `109` - -Service Name: Управление днс-зонами и записями - -[Manual](zones_v2.md) | [Create params](zones_v2_params_create.md) | [Modify params](zones_v2_params_modify.md) | [Output params](zones_v2_outputs.md) | [Operations](zones_v2_ops.md) | [Example](zones_v2_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](zones_v2_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](zones_v2_params_modify.md) diff --git a/generated/dev/docs/zones_v2_outputs.md b/generated/dev/docs/zones_v2_outputs.md deleted file mode 100644 index 7d38f81..0000000 --- a/generated/dev/docs/zones_v2_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_zones_v2 - -Service ID: `109` - -Service Name: Управление днс-зонами и записями - -[Manual](zones_v2.md) | [Create params](zones_v2_params_create.md) | [Modify params](zones_v2_params_modify.md) | [Output params](zones_v2_outputs.md) | [Operations](zones_v2_ops.md) | [Example](zones_v2_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/dev/docs/zones_v2_params.md b/generated/dev/docs/zones_v2_params.md deleted file mode 100644 index fa69049..0000000 --- a/generated/dev/docs/zones_v2_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_zones_v2 - -Service ID: `109` - -Service Name: Управление днс-зонами и записями - -[Manual](zones_v2.md) | [Create params](zones_v2_params_create.md) | [Modify params](zones_v2_params_modify.md) | [Output params](zones_v2_outputs.md) | [Operations](zones_v2_ops.md) | [Example](zones_v2_example.md) - -## Parameters - -- [Create params](zones_v2_params_create.md) -- [Modify params](zones_v2_params_modify.md) diff --git a/generated/dev/docs/zones_v2_params_create.md b/generated/dev/docs/zones_v2_params_create.md deleted file mode 100644 index 98dab0e..0000000 --- a/generated/dev/docs/zones_v2_params_create.md +++ /dev/null @@ -1,30 +0,0 @@ -# Resource nubes_zones_v2 - -Service ID: `109` - -Service Name: Управление днс-зонами и записями - -[Manual](zones_v2.md) | [Create params](zones_v2_params_create.md) | [Modify params](zones_v2_params_modify.md) | [Output params](zones_v2_outputs.md) | [Operations](zones_v2_ops.md) | [Example](zones_v2_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
761zone_namestringИмя зоныregex=^([a-z0-9-]+\.)+[a-z0-9-]+$; maxlength=64; minlength=1
763zone_masters_for_slavestringПример:
**8.8.8.8 8.8.4.4**
768resource_realmstringfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
762zone_kindstringNATIVEТип зоныvalue_list=NATIVE, SLAVE
764zone_time_to_refreshinteger86400Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверовminvalue=600
765zone_time_to_retryinteger7200Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверовminvalue=600
766zone_time_to_expireinteger3600000Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичнымminvalue=3600
767zone_time_to_liveinteger86400Время, в течение которого информация будет кешироваться другими DNS-серверамиminvalue=600
diff --git a/generated/dev/docs/zones_v2_params_modify.md b/generated/dev/docs/zones_v2_params_modify.md deleted file mode 100644 index 4987357..0000000 --- a/generated/dev/docs/zones_v2_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_zones_v2 - -Service ID: `109` - -Service Name: Управление днс-зонами и записями - -[Manual](zones_v2.md) | [Create params](zones_v2_params_create.md) | [Modify params](zones_v2_params_modify.md) | [Output params](zones_v2_outputs.md) | [Operations](zones_v2_ops.md) | [Example](zones_v2_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
769recordsarray-map-fixed
diff --git a/generated/dev/go/.gitkeep b/generated/dev/go/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/dev/go/109_zones_v2_resource.go b/generated/dev/go/109_zones_v2_resource.go deleted file mode 100644 index 6328798..0000000 --- a/generated/dev/go/109_zones_v2_resource.go +++ /dev/null @@ -1,467 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: zones_v2 -// Service ID: 109 - -var _ resource.Resource = &ZonesV2Resource{} -var _ resource.ResourceWithModifyPlan = &ZonesV2Resource{} -var _ resource.ResourceWithImportState = &ZonesV2Resource{} - -type ZonesV2Resource struct { - client *core.UniversalClient -} - -type ZonesV2Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Records types.String `tfsdk:"records"` - ResourceRealm types.String `tfsdk:"resource_realm"` - ZoneKind types.String `tfsdk:"zone_kind"` - ZoneMastersForSlave types.String `tfsdk:"zone_masters_for_slave"` - ZoneName types.String `tfsdk:"zone_name"` - ZoneTimeToExpire types.Int64 `tfsdk:"zone_time_to_expire"` - ZoneTimeToLive types.Int64 `tfsdk:"zone_time_to_live"` - ZoneTimeToRefresh types.Int64 `tfsdk:"zone_time_to_refresh"` - ZoneTimeToRetry types.Int64 `tfsdk:"zone_time_to_retry"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewZonesV2Resource() resource.Resource { - return &ZonesV2Resource{} -} - -func (r *ZonesV2Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_zones_v2" -} - -func (r *ZonesV2Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "records": schema.StringAttribute{Required: true}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "zone_kind": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("NATIVE"), MarkdownDescription: "Тип зоны Не изменяется после создания."}, - "zone_masters_for_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Использовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов Не изменяется после создания."}, - "zone_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя зоны Не изменяется после создания."}, - "zone_time_to_expire": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(3600000), MarkdownDescription: "Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным Не изменяется после создания."}, - "zone_time_to_live": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(86400), MarkdownDescription: "Время, в течение которого информация будет кешироваться другими DNS-серверами Не изменяется после создания."}, - "zone_time_to_refresh": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(86400), MarkdownDescription: "Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов Не изменяется после создания."}, - "zone_time_to_retry": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(7200), MarkdownDescription: "Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ZonesV2Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *ZonesV2Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *ZonesV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan ZonesV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneKind.IsNull() && !plan.ZoneKind.IsUnknown() && !state.ZoneKind.IsNull() && !state.ZoneKind.IsUnknown() { - if plan.ZoneKind.ValueString() != state.ZoneKind.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_kind", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneMastersForSlave.IsNull() && !plan.ZoneMastersForSlave.IsUnknown() && !state.ZoneMastersForSlave.IsNull() && !state.ZoneMastersForSlave.IsUnknown() { - if plan.ZoneMastersForSlave.ValueString() != state.ZoneMastersForSlave.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_masters_for_slave", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneName.IsNull() && !plan.ZoneName.IsUnknown() && !state.ZoneName.IsNull() && !state.ZoneName.IsUnknown() { - if plan.ZoneName.ValueString() != state.ZoneName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToExpire.IsNull() && !plan.ZoneTimeToExpire.IsUnknown() && !state.ZoneTimeToExpire.IsNull() && !state.ZoneTimeToExpire.IsUnknown() { - if plan.ZoneTimeToExpire.ValueInt64() != state.ZoneTimeToExpire.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_expire", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToLive.IsNull() && !plan.ZoneTimeToLive.IsUnknown() && !state.ZoneTimeToLive.IsNull() && !state.ZoneTimeToLive.IsUnknown() { - if plan.ZoneTimeToLive.ValueInt64() != state.ZoneTimeToLive.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_live", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToRefresh.IsNull() && !plan.ZoneTimeToRefresh.IsUnknown() && !state.ZoneTimeToRefresh.IsNull() && !state.ZoneTimeToRefresh.IsUnknown() { - if plan.ZoneTimeToRefresh.ValueInt64() != state.ZoneTimeToRefresh.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_refresh", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToRetry.IsNull() && !plan.ZoneTimeToRetry.IsUnknown() && !state.ZoneTimeToRetry.IsNull() && !state.ZoneTimeToRetry.IsUnknown() { - if plan.ZoneTimeToRetry.ValueInt64() != state.ZoneTimeToRetry.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_retry", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Records.IsNull() || config.Records.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "records is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ZoneName.IsNull() || config.ZoneName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_name is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 761: resources_core.FormatString(config.ZoneName), - 762: resources_core.FormatString(config.ZoneKind), - 763: resources_core.FormatString(config.ZoneMastersForSlave), - 764: resources_core.FormatInt64(config.ZoneTimeToRefresh), - 765: resources_core.FormatInt64(config.ZoneTimeToRetry), - 766: resources_core.FormatInt64(config.ZoneTimeToExpire), - 767: resources_core.FormatInt64(config.ZoneTimeToLive), - 768: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 109, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *ZonesV2Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data ZonesV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Records.IsNull() || data.Records.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "records is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.ZoneName.IsNull() || data.ZoneName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_name is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 109, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 761: resources_core.FormatString(data.ZoneName), - 762: resources_core.FormatString(data.ZoneKind), - 763: resources_core.FormatString(data.ZoneMastersForSlave), - 764: resources_core.FormatInt64(data.ZoneTimeToRefresh), - 765: resources_core.FormatInt64(data.ZoneTimeToRetry), - 766: resources_core.FormatInt64(data.ZoneTimeToExpire), - 767: resources_core.FormatInt64(data.ZoneTimeToLive), - 768: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 109, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 109, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "records", Field: "Records", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "int64"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "int64"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "int64"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ZonesV2Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ZonesV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 109, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "records", Field: "Records", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "int64"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "int64"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "int64"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *ZonesV2Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ZonesV2Model - var state ZonesV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.Records.IsNull() != state.Records.IsNull() || plan.Records.IsUnknown() != state.Records.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.Records.IsNull() && !plan.Records.IsUnknown() && !state.Records.IsNull() && !state.Records.IsUnknown() { - if plan.Records.ValueString() != state.Records.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 769: resources_core.FormatString(plan.Records), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 109, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "records", Field: "Records", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "int64"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "int64"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "int64"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ZonesV2Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ZonesV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *ZonesV2Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *ZonesV2Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/110_dnszone_resource.go b/generated/dev/go/110_dnszone_resource.go deleted file mode 100644 index fe1cff6..0000000 --- a/generated/dev/go/110_dnszone_resource.go +++ /dev/null @@ -1,463 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dnszone -// Service ID: 110 - -var _ resource.Resource = &DnszoneResource{} -var _ resource.ResourceWithModifyPlan = &DnszoneResource{} -var _ resource.ResourceWithImportState = &DnszoneResource{} - -type DnszoneResource struct { - client *core.UniversalClient -} - -type DnszoneModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ResourceRealm types.String `tfsdk:"resource_realm"` - ZoneEmail types.String `tfsdk:"zone_email"` - ZoneKind types.String `tfsdk:"zone_kind"` - ZoneMastersForSlave types.String `tfsdk:"zone_masters_for_slave"` - ZoneName types.String `tfsdk:"zone_name"` - ZoneTimeToExpire types.String `tfsdk:"zone_time_to_expire"` - ZoneTimeToLive types.String `tfsdk:"zone_time_to_live"` - ZoneTimeToRefresh types.String `tfsdk:"zone_time_to_refresh"` - ZoneTimeToRetry types.String `tfsdk:"zone_time_to_retry"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDnszoneResource() resource.Resource { - return &DnszoneResource{} -} - -func (r *DnszoneResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dnszone" -} - -func (r *DnszoneResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "zone_email": schema.StringAttribute{Required: true, MarkdownDescription: "Контактный e-mail Не изменяется после создания."}, - "zone_kind": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("NATIVE"), MarkdownDescription: "Тип зоны Не изменяется после создания."}, - "zone_masters_for_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Использовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов Не изменяется после создания."}, - "zone_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя зоны Не изменяется после создания."}, - "zone_time_to_expire": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("3600000"), MarkdownDescription: "Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным Не изменяется после создания."}, - "zone_time_to_live": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("86400"), MarkdownDescription: "Время, в течение которого информация будет кешироваться другими DNS-серверами Не изменяется после создания."}, - "zone_time_to_refresh": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("86400"), MarkdownDescription: "Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов Не изменяется после создания."}, - "zone_time_to_retry": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("7200"), MarkdownDescription: "Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DnszoneResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DnszoneModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneEmail.IsNull() && !plan.ZoneEmail.IsUnknown() && !state.ZoneEmail.IsNull() && !state.ZoneEmail.IsUnknown() { - if plan.ZoneEmail.ValueString() != state.ZoneEmail.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_email", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneKind.IsNull() && !plan.ZoneKind.IsUnknown() && !state.ZoneKind.IsNull() && !state.ZoneKind.IsUnknown() { - if plan.ZoneKind.ValueString() != state.ZoneKind.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_kind", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneMastersForSlave.IsNull() && !plan.ZoneMastersForSlave.IsUnknown() && !state.ZoneMastersForSlave.IsNull() && !state.ZoneMastersForSlave.IsUnknown() { - if plan.ZoneMastersForSlave.ValueString() != state.ZoneMastersForSlave.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_masters_for_slave", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneName.IsNull() && !plan.ZoneName.IsUnknown() && !state.ZoneName.IsNull() && !state.ZoneName.IsUnknown() { - if plan.ZoneName.ValueString() != state.ZoneName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToExpire.IsNull() && !plan.ZoneTimeToExpire.IsUnknown() && !state.ZoneTimeToExpire.IsNull() && !state.ZoneTimeToExpire.IsUnknown() { - if plan.ZoneTimeToExpire.ValueString() != state.ZoneTimeToExpire.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_expire", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToLive.IsNull() && !plan.ZoneTimeToLive.IsUnknown() && !state.ZoneTimeToLive.IsNull() && !state.ZoneTimeToLive.IsUnknown() { - if plan.ZoneTimeToLive.ValueString() != state.ZoneTimeToLive.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_live", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToRefresh.IsNull() && !plan.ZoneTimeToRefresh.IsUnknown() && !state.ZoneTimeToRefresh.IsNull() && !state.ZoneTimeToRefresh.IsUnknown() { - if plan.ZoneTimeToRefresh.ValueString() != state.ZoneTimeToRefresh.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_refresh", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToRetry.IsNull() && !plan.ZoneTimeToRetry.IsUnknown() && !state.ZoneTimeToRetry.IsNull() && !state.ZoneTimeToRetry.IsUnknown() { - if plan.ZoneTimeToRetry.ValueString() != state.ZoneTimeToRetry.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_retry", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ZoneEmail.IsNull() || config.ZoneEmail.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_email is required.") - return - } - if config.ZoneName.IsNull() || config.ZoneName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_name is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 66: resources_core.FormatString(config.ZoneEmail), - 67: resources_core.FormatString(config.ZoneName), - 68: resources_core.FormatString(config.ZoneKind), - 69: resources_core.FormatString(config.ZoneMastersForSlave), - 70: resources_core.FormatString(config.ZoneTimeToRefresh), - 71: resources_core.FormatString(config.ZoneTimeToRetry), - 72: resources_core.FormatString(config.ZoneTimeToExpire), - 73: resources_core.FormatString(config.ZoneTimeToLive), - 284: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 110, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DnszoneResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.ZoneEmail.IsNull() || data.ZoneEmail.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_email is required.") - return - } - if data.ZoneName.IsNull() || data.ZoneName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_name is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 110, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 66: resources_core.FormatString(data.ZoneEmail), - 67: resources_core.FormatString(data.ZoneName), - 68: resources_core.FormatString(data.ZoneKind), - 69: resources_core.FormatString(data.ZoneMastersForSlave), - 70: resources_core.FormatString(data.ZoneTimeToRefresh), - 71: resources_core.FormatString(data.ZoneTimeToRetry), - 72: resources_core.FormatString(data.ZoneTimeToExpire), - 73: resources_core.FormatString(data.ZoneTimeToLive), - 284: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 110, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 110, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnszoneResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 110, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DnszoneResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DnszoneModel - var state DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 110, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnszoneResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DnszoneResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DnszoneResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/111_dnsrecord_resource.go b/generated/dev/go/111_dnsrecord_resource.go deleted file mode 100644 index 89c2a20..0000000 --- a/generated/dev/go/111_dnsrecord_resource.go +++ /dev/null @@ -1,482 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dnsrecord -// Service ID: 111 - -var _ resource.Resource = &DnsrecordResource{} -var _ resource.ResourceWithModifyPlan = &DnsrecordResource{} -var _ resource.ResourceWithImportState = &DnsrecordResource{} - -type DnsrecordResource struct { - client *core.UniversalClient -} - -type DnsrecordModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - RecordInput types.String `tfsdk:"record_input"` - RecordName types.String `tfsdk:"record_name"` - RecordTTL types.Int64 `tfsdk:"record_t_t_l"` - RecordType types.String `tfsdk:"record_type"` - ZoneUid types.String `tfsdk:"zone_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDnsrecordResource() resource.Resource { - return &DnsrecordResource{} -} - -func (r *DnsrecordResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dnsrecord" -} - -func (r *DnsrecordResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "record_input": schema.StringAttribute{Required: true, MarkdownDescription: "Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP"}, - "record_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя записи. Имя зоны в конце проставляется автоматически Не изменяется после создания."}, - "record_t_t_l": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(3600), MarkdownDescription: "Time-to-Leave записи. Раз в какое время запись будет обновлена Не изменяется после создания."}, - "record_type": schema.StringAttribute{Required: true, MarkdownDescription: "Тип DNS-записи Не изменяется после создания."}, - "zone_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID экземпляра услуги DNS-зоны Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DnsrecordResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DnsrecordModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.ZoneUid.IsNull() && !plan.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, plan.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != plan.ZoneUid.ValueString() { - plan.ZoneUid = types.StringValue(resolvedZoneUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.RecordName.IsNull() && !plan.RecordName.IsUnknown() && !state.RecordName.IsNull() && !state.RecordName.IsUnknown() { - if plan.RecordName.ValueString() != state.RecordName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить record_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RecordTTL.IsNull() && !plan.RecordTTL.IsUnknown() && !state.RecordTTL.IsNull() && !state.RecordTTL.IsUnknown() { - if plan.RecordTTL.ValueInt64() != state.RecordTTL.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить record_t_t_l", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RecordType.IsNull() && !plan.RecordType.IsUnknown() && !state.RecordType.IsNull() && !state.RecordType.IsUnknown() { - if plan.RecordType.ValueString() != state.RecordType.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить record_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneUid.IsNull() && !plan.ZoneUid.IsUnknown() && !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - if plan.ZoneUid.ValueString() != state.ZoneUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.RecordInput.IsNull() || config.RecordInput.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_input is required.") - return - } - if config.RecordName.IsNull() || config.RecordName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_name is required.") - return - } - if config.RecordType.IsNull() || config.RecordType.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_type is required.") - return - } - if config.ZoneUid.IsNull() || config.ZoneUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.ZoneUid.IsNull() && !config.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, config.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != config.ZoneUid.ValueString() { - config.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - params := map[int]string{ - 75: resources_core.FormatString(config.ZoneUid), - 76: resources_core.FormatString(config.RecordType), - 77: resources_core.FormatString(config.RecordName), - 78: resources_core.FormatString(config.RecordInput), - 450: resources_core.FormatInt64(config.RecordTTL), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 111, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DnsrecordResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.RecordInput.IsNull() || data.RecordInput.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_input is required.") - return - } - if data.RecordName.IsNull() || data.RecordName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_name is required.") - return - } - if data.RecordType.IsNull() || data.RecordType.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_type is required.") - return - } - if data.ZoneUid.IsNull() || data.ZoneUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_uid is required.") - return - } - if !data.ZoneUid.IsNull() && !data.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, data.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedZoneUid != "" && resolvedZoneUid != data.ZoneUid.ValueString() { - data.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 111, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 75: resources_core.FormatString(data.ZoneUid), - 76: resources_core.FormatString(data.RecordType), - 77: resources_core.FormatString(data.RecordName), - 78: resources_core.FormatString(data.RecordInput), - 450: resources_core.FormatInt64(data.RecordTTL), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 111, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 111, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, state.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != state.ZoneUid.ValueString() { - state.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnsrecordResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 111, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.ZoneUid.IsNull() && !newState.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, newState.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != newState.ZoneUid.ValueString() { - newState.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DnsrecordResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DnsrecordModel - var state DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.RecordInput.IsNull() != state.RecordInput.IsNull() || plan.RecordInput.IsUnknown() != state.RecordInput.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.RecordInput.IsNull() && !plan.RecordInput.IsUnknown() && !state.RecordInput.IsNull() && !state.RecordInput.IsUnknown() { - if plan.RecordInput.ValueString() != state.RecordInput.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 256: resources_core.FormatString(plan.RecordInput), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 111, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, state.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != state.ZoneUid.ValueString() { - state.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnsrecordResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DnsrecordResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DnsrecordResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/115_mariadb_database_resource.go b/generated/dev/go/115_mariadb_database_resource.go deleted file mode 100644 index d5f4642..0000000 --- a/generated/dev/go/115_mariadb_database_resource.go +++ /dev/null @@ -1,350 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mariadb -// Subresource: database - -var _ resource.Resource = &MariadbDatabaseResource{} - -// MariadbDatabaseResource manages a subresource via operations. -type MariadbDatabaseResource struct { - client *core.UniversalClient -} - -type MariadbDatabaseModel struct { - ID types.String `tfsdk:"id"` - MariadbID types.String `tfsdk:"mariadb_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DatabaseName types.String `tfsdk:"database_name"` -} - -func NewMariadbDatabaseResource() resource.Resource { - return &MariadbDatabaseResource{} -} - -func (r *MariadbDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mariadb_database" -} - -func (r *MariadbDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "mariadb_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "database_name": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `db01` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MariadbDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan MariadbDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.DatabaseName.IsNull() || plan.DatabaseName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "database_name is required.") - return - } - - instanceUID := strings.TrimSpace(plan.MariadbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - } - identityCodes := []string{ - "databaseName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MariadbDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MariadbDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MariadbDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state MariadbDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.MariadbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MariadbDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MariadbDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_database" == "" { - return - } - - instanceUID := strings.TrimSpace(state.MariadbID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(state.DatabaseName), - } - identityCodes := []string{ - "databaseName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "databaseName": resources_core.FormatString(state.DatabaseName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_database", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *MariadbDatabaseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/115_mariadb_resource.go b/generated/dev/go/115_mariadb_resource.go deleted file mode 100644 index c514065..0000000 --- a/generated/dev/go/115_mariadb_resource.go +++ /dev/null @@ -1,590 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mariadb -// Service ID: 115 - -var _ resource.Resource = &MariadbResource{} -var _ resource.ResourceWithModifyPlan = &MariadbResource{} -var _ resource.ResourceWithImportState = &MariadbResource{} - -type MariadbResource struct { - client *core.UniversalClient -} - -type MariadbModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AppVersion types.String `tfsdk:"app_version"` - AutoScale types.Bool `tfsdk:"auto_scale"` - AutoScalePercentage types.Int64 `tfsdk:"auto_scale_percentage"` - AutoScaleQuotaGb types.Int64 `tfsdk:"auto_scale_quota_gb"` - AutoScaleTechWindow types.Int64 `tfsdk:"auto_scale_tech_window"` - ExtBACKUPSCHEDULE types.String `tfsdk:"ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewMariadbResource() resource.Resource { - return &MariadbResource{} -} - -func (r *MariadbResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mariadb" -} - -func (r *MariadbResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("9.4.0"), MarkdownDescription: "Версия MySQL Не изменяется после создания."}, - "auto_scale": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги"}, - "auto_scale_percentage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема"}, - "auto_scale_quota_gb": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота для autoScale"}, - "auto_scale_tech_window": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23)"}, - "ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("0 * * * *"), MarkdownDescription: "Не обязательный. Время запуска бекапа"}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к master"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores)"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MariadbResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *MariadbModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() { - plan.S3Uid = types.StringValue(resolvedS3Uid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить app_version", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - if plan.S3Uid.ValueString() != state.S3Uid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 422: resources_core.FormatString(config.ResourceRealm), - 424: resources_core.FormatInt64(config.ResourceCPU), - 425: resources_core.FormatInt64(config.ResourceMemory), - 426: resources_core.FormatInt64(config.ResourceDisk), - 427: resources_core.FormatInt64(config.ResourceInstances), - 428: resources_core.FormatBool(config.NeedExternalAddressMaster), - 429: resources_core.FormatString(config.IpSpaceNameMaster), - 430: resources_core.FormatString(config.ExtBACKUPSCHEDULE), - 431: resources_core.FormatString(config.AppVersion), - 432: resources_core.FormatBool(config.AutoScale), - 433: resources_core.FormatInt64(config.AutoScalePercentage), - 434: resources_core.FormatInt64(config.AutoScaleTechWindow), - 435: resources_core.FormatInt64(config.AutoScaleQuotaGb), - 459: resources_core.FormatString(config.S3Uid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 115, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *MariadbResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 115, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 422: resources_core.FormatString(data.ResourceRealm), - 424: resources_core.FormatInt64(data.ResourceCPU), - 425: resources_core.FormatInt64(data.ResourceMemory), - 426: resources_core.FormatInt64(data.ResourceDisk), - 427: resources_core.FormatInt64(data.ResourceInstances), - 428: resources_core.FormatBool(data.NeedExternalAddressMaster), - 429: resources_core.FormatString(data.IpSpaceNameMaster), - 430: resources_core.FormatString(data.ExtBACKUPSCHEDULE), - 431: resources_core.FormatString(data.AppVersion), - 432: resources_core.FormatBool(data.AutoScale), - 433: resources_core.FormatInt64(data.AutoScalePercentage), - 434: resources_core.FormatInt64(data.AutoScaleTechWindow), - 435: resources_core.FormatInt64(data.AutoScaleQuotaGb), - 459: resources_core.FormatString(data.S3Uid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 115, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 115, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "int64"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 115, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "int64"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *MariadbResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MariadbModel - var state MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPSCHEDULE.IsNull() != state.ExtBACKUPSCHEDULE.IsNull() || plan.ExtBACKUPSCHEDULE.IsUnknown() != state.ExtBACKUPSCHEDULE.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPSCHEDULE.IsNull() && !plan.ExtBACKUPSCHEDULE.IsUnknown() && !state.ExtBACKUPSCHEDULE.IsNull() && !state.ExtBACKUPSCHEDULE.IsUnknown() { - if plan.ExtBACKUPSCHEDULE.ValueString() != state.ExtBACKUPSCHEDULE.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoScale.IsNull() != state.AutoScale.IsNull() || plan.AutoScale.IsUnknown() != state.AutoScale.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoScale.IsNull() && !plan.AutoScale.IsUnknown() && !state.AutoScale.IsNull() && !state.AutoScale.IsUnknown() { - if plan.AutoScale.ValueBool() != state.AutoScale.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoScalePercentage.IsNull() != state.AutoScalePercentage.IsNull() || plan.AutoScalePercentage.IsUnknown() != state.AutoScalePercentage.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoScalePercentage.IsNull() && !plan.AutoScalePercentage.IsUnknown() && !state.AutoScalePercentage.IsNull() && !state.AutoScalePercentage.IsUnknown() { - if plan.AutoScalePercentage.ValueInt64() != state.AutoScalePercentage.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoScaleTechWindow.IsNull() != state.AutoScaleTechWindow.IsNull() || plan.AutoScaleTechWindow.IsUnknown() != state.AutoScaleTechWindow.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoScaleTechWindow.IsNull() && !plan.AutoScaleTechWindow.IsUnknown() && !state.AutoScaleTechWindow.IsNull() && !state.AutoScaleTechWindow.IsUnknown() { - if plan.AutoScaleTechWindow.ValueInt64() != state.AutoScaleTechWindow.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoScaleQuotaGb.IsNull() != state.AutoScaleQuotaGb.IsNull() || plan.AutoScaleQuotaGb.IsUnknown() != state.AutoScaleQuotaGb.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoScaleQuotaGb.IsNull() && !plan.AutoScaleQuotaGb.IsUnknown() && !state.AutoScaleQuotaGb.IsNull() && !state.AutoScaleQuotaGb.IsUnknown() { - if plan.AutoScaleQuotaGb.ValueInt64() != state.AutoScaleQuotaGb.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 436: resources_core.FormatInt64(plan.ResourceCPU), - 437: resources_core.FormatInt64(plan.ResourceMemory), - 438: resources_core.FormatInt64(plan.ResourceInstances), - 439: resources_core.FormatInt64(plan.ResourceDisk), - 440: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 441: resources_core.FormatString(plan.IpSpaceNameMaster), - 442: resources_core.FormatString(plan.ExtBACKUPSCHEDULE), - 443: resources_core.FormatBool(plan.AutoScale), - 444: resources_core.FormatInt64(plan.AutoScalePercentage), - 445: resources_core.FormatInt64(plan.AutoScaleTechWindow), - 446: resources_core.FormatInt64(plan.AutoScaleQuotaGb), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 115, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "int64"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *MariadbResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *MariadbResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/115_mariadb_user_resource.go b/generated/dev/go/115_mariadb_user_resource.go deleted file mode 100644 index 8c17b91..0000000 --- a/generated/dev/go/115_mariadb_user_resource.go +++ /dev/null @@ -1,386 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mariadb -// Subresource: user - -var _ resource.Resource = &MariadbUserResource{} - -// MariadbUserResource manages a subresource via operations. -type MariadbUserResource struct { - client *core.UniversalClient -} - -type MariadbUserModel struct { - ID types.String `tfsdk:"id"` - MariadbID types.String `tfsdk:"mariadb_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessHosts types.String `tfsdk:"access_hosts"` - DatabaseName types.String `tfsdk:"database_name"` - Password types.String `tfsdk:"password"` - Username types.String `tfsdk:"username"` -} - -func NewMariadbUserResource() resource.Resource { - return &MariadbUserResource{} -} - -func (r *MariadbUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mariadb_user" -} - -func (r *MariadbUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "mariadb_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_hosts": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `%` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "database_name": schema.StringAttribute{Required: true, MarkdownDescription: "Необходимо указать массив существующих баз Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "password": schema.StringAttribute{Required: true, MarkdownDescription: "Секрет будет записан в хранилище секретов и не будет отображаться публично Не изменяется после создания. Изменение требует пересоздания.", Sensitive: true, PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `myusername` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MariadbUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan MariadbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.AccessHosts.IsNull() || plan.AccessHosts.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_hosts is required.") - return - } - if plan.DatabaseName.IsNull() || plan.DatabaseName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "database_name is required.") - return - } - if plan.Password.IsNull() || plan.Password.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "password is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.MariadbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "password": resources_core.FormatString(plan.Password), - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "accessHosts", - "databaseName", - "password", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "password": resources_core.FormatString(plan.Password), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MariadbUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MariadbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MariadbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state MariadbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.MariadbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "password": resources_core.FormatString(plan.Password), - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MariadbUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MariadbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.MariadbID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(state.AccessHosts), - "databaseName": resources_core.FormatString(state.DatabaseName), - "password": resources_core.FormatString(state.Password), - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "accessHosts", - "databaseName", - "password", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *MariadbUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/116_kafka_resource.go b/generated/dev/go/116_kafka_resource.go deleted file mode 100644 index e4bbe7f..0000000 --- a/generated/dev/go/116_kafka_resource.go +++ /dev/null @@ -1,480 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Service ID: 116 - -var _ resource.Resource = &KafkaResource{} -var _ resource.ResourceWithModifyPlan = &KafkaResource{} -var _ resource.ResourceWithImportState = &KafkaResource{} - -type KafkaResource struct { - client *core.UniversalClient -} - -type KafkaModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewKafkaResource() resource.Resource { - return &KafkaResource{} -} - -func (r *KafkaResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka" -} - -func (r *KafkaResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`"}, - "resource_c_p_u": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2000`"}, - "resource_disk": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `20`"}, - "resource_instances": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2`"}, - "resource_memory": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *KafkaModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceCPU.IsNull() || config.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if config.ResourceDisk.IsNull() || config.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if config.ResourceInstances.IsNull() || config.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if config.ResourceMemory.IsNull() || config.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 461: resources_core.FormatInt64(config.ResourceInstances), - 462: resources_core.FormatInt64(config.ResourceMemory), - 463: resources_core.FormatInt64(config.ResourceCPU), - 464: resources_core.FormatInt64(config.ResourceDisk), - 465: resources_core.FormatBool(config.NeedExternalAddressMaster), - 466: resources_core.FormatString(config.IpSpaceNameMaster), - 469: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 116, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *KafkaResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceCPU.IsNull() || data.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if data.ResourceDisk.IsNull() || data.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if data.ResourceInstances.IsNull() || data.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if data.ResourceMemory.IsNull() || data.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 116, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 461: resources_core.FormatInt64(data.ResourceInstances), - 462: resources_core.FormatInt64(data.ResourceMemory), - 463: resources_core.FormatInt64(data.ResourceCPU), - 464: resources_core.FormatInt64(data.ResourceDisk), - 465: resources_core.FormatBool(data.NeedExternalAddressMaster), - 466: resources_core.FormatString(data.IpSpaceNameMaster), - 469: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 116, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 116, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 116, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *KafkaResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaModel - var state KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 501: resources_core.FormatInt64(plan.ResourceInstances), - 502: resources_core.FormatInt64(plan.ResourceMemory), - 503: resources_core.FormatInt64(plan.ResourceCPU), - 504: resources_core.FormatInt64(plan.ResourceDisk), - 505: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 506: resources_core.FormatString(plan.IpSpaceNameMaster), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 116, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *KafkaResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *KafkaResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/116_kafka_topic_resource.go b/generated/dev/go/116_kafka_topic_resource.go deleted file mode 100644 index 0b05fff..0000000 --- a/generated/dev/go/116_kafka_topic_resource.go +++ /dev/null @@ -1,368 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Subresource: topic - -var _ resource.Resource = &KafkaTopicResource{} - -// KafkaTopicResource manages a subresource via operations. -type KafkaTopicResource struct { - client *core.UniversalClient -} - -type KafkaTopicModel struct { - ID types.String `tfsdk:"id"` - KafkaID types.String `tfsdk:"kafka_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - NameTopic types.String `tfsdk:"name_topic"` - Partitions types.Int64 `tfsdk:"partitions"` - Replicas types.Int64 `tfsdk:"replicas"` -} - -func NewKafkaTopicResource() resource.Resource { - return &KafkaTopicResource{} -} - -func (r *KafkaTopicResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka_topic" -} - -func (r *KafkaTopicResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "kafka_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events` Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "partitions": schema.Int64Attribute{Required: true, MarkdownDescription: "Число партиций можно увеличить, но уменьшить их нельзя."}, - "replicas": schema.Int64Attribute{Required: true, MarkdownDescription: "Количество реплик не может привышать количество реплик брокера"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaTopicResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan KafkaTopicModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.NameTopic.IsNull() || plan.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if plan.Partitions.IsNull() || plan.Partitions.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "partitions is required.") - return - } - if plan.Replicas.IsNull() || plan.Replicas.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "replicas is required.") - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - } - identityCodes := []string{ - "nameTopic", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("topic", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "partitions": resources_core.FormatInt64(plan.Partitions), - "replicas": resources_core.FormatInt64(plan.Replicas), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_topic", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_topic", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaTopicResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaTopicResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaTopicModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_topic" == "" { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "partitions": resources_core.FormatInt64(plan.Partitions), - "replicas": resources_core.FormatInt64(plan.Replicas), - }) - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_topic", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaTopicResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_topic" == "" { - return - } - - instanceUID := strings.TrimSpace(state.KafkaID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(state.NameTopic), - } - identityCodes := []string{ - "nameTopic", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("topic", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(state.NameTopic), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_topic", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *KafkaTopicResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/116_kafka_user_resource.go b/generated/dev/go/116_kafka_user_resource.go deleted file mode 100644 index e1bf992..0000000 --- a/generated/dev/go/116_kafka_user_resource.go +++ /dev/null @@ -1,384 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Subresource: user - -var _ resource.Resource = &KafkaUserResource{} - -// KafkaUserResource manages a subresource via operations. -type KafkaUserResource struct { - client *core.UniversalClient -} - -type KafkaUserModel struct { - ID types.String `tfsdk:"id"` - KafkaID types.String `tfsdk:"kafka_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessHosts types.String `tfsdk:"access_hosts"` - Group types.String `tfsdk:"group"` - NameTopic types.String `tfsdk:"name_topic"` - Operations types.String `tfsdk:"operations"` - Username types.String `tfsdk:"username"` -} - -func NewKafkaUserResource() resource.Resource { - return &KafkaUserResource{} -} - -func (r *KafkaUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka_user" -} - -func (r *KafkaUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "kafka_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_hosts": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `192.168.1.0/24` или `*`"}, - "group": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `order-consumers` или `*`"}, - "name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`"}, - "operations": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `Create, Describe, Read, Write`"}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `username-admin` Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan KafkaUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.AccessHosts.IsNull() || plan.AccessHosts.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_hosts is required.") - return - } - if plan.Group.IsNull() || plan.Group.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "group is required.") - return - } - if plan.NameTopic.IsNull() || plan.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if plan.Operations.IsNull() || plan.Operations.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "operations is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "nameTopic": resources_core.FormatString(plan.NameTopic), - "operations": resources_core.FormatString(plan.Operations), - "group": resources_core.FormatString(plan.Group), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_user" == "" { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "operations": resources_core.FormatString(plan.Operations), - "group": resources_core.FormatString(plan.Group), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "username": resources_core.FormatString(plan.Username), - }) - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_user", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.KafkaID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *KafkaUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/119_akhq_resource.go b/generated/dev/go/119_akhq_resource.go deleted file mode 100644 index d7e6a84..0000000 --- a/generated/dev/go/119_akhq_resource.go +++ /dev/null @@ -1,496 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: akhq -// Service ID: 119 - -var _ resource.Resource = &AkhqResource{} -var _ resource.ResourceWithModifyPlan = &AkhqResource{} -var _ resource.ResourceWithImportState = &AkhqResource{} - -type AkhqResource struct { - client *core.UniversalClient -} - -type AkhqModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - KafkaUid types.String `tfsdk:"kafka_uid"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewAkhqResource() resource.Resource { - return &AkhqResource{} -} - -func (r *AkhqResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_akhq" -} - -func (r *AkhqResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "kafka_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать кластер из списка"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Пример: `1000` Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Пример: `1024` Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *AkhqResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *AkhqModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, plan.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != plan.KafkaUid.ValueString() { - plan.KafkaUid = types.StringValue(resolvedKafkaUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() || config.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.KafkaUid.IsNull() || config.KafkaUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.KafkaUid.IsNull() && !config.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, config.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != config.KafkaUid.ValueString() { - config.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - params := map[int]string{ - 550: resources_core.FormatString(config.ResourceRealm), - 551: resources_core.FormatInt64(config.ResourceMemory), - 552: resources_core.FormatInt64(config.ResourceCPU), - 553: resources_core.FormatString(config.Domain), - 554: resources_core.FormatInt64(config.ResourceInstances), - 555: resources_core.FormatString(config.KafkaUid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 119, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *AkhqResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.KafkaUid.IsNull() || data.KafkaUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if !data.KafkaUid.IsNull() && !data.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, data.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedKafkaUid != "" && resolvedKafkaUid != data.KafkaUid.ValueString() { - data.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 119, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 550: resources_core.FormatString(data.ResourceRealm), - 551: resources_core.FormatInt64(data.ResourceMemory), - 552: resources_core.FormatInt64(data.ResourceCPU), - 553: resources_core.FormatString(data.Domain), - 554: resources_core.FormatInt64(data.ResourceInstances), - 555: resources_core.FormatString(data.KafkaUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 119, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 119, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *AkhqResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 119, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, newState.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != newState.KafkaUid.ValueString() { - newState.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *AkhqResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan AkhqModel - var state AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.KafkaUid.IsNull() != state.KafkaUid.IsNull() || plan.KafkaUid.IsUnknown() != state.KafkaUid.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - if plan.KafkaUid.ValueString() != state.KafkaUid.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 565: resources_core.FormatString(plan.KafkaUid), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 119, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *AkhqResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *AkhqResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *AkhqResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/120_clickhouse_database_resource.go b/generated/dev/go/120_clickhouse_database_resource.go deleted file mode 100644 index e177abb..0000000 --- a/generated/dev/go/120_clickhouse_database_resource.go +++ /dev/null @@ -1,350 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Subresource: database - -var _ resource.Resource = &ClickhouseDatabaseResource{} - -// ClickhouseDatabaseResource manages a subresource via operations. -type ClickhouseDatabaseResource struct { - client *core.UniversalClient -} - -type ClickhouseDatabaseModel struct { - ID types.String `tfsdk:"id"` - ClickhouseID types.String `tfsdk:"clickhouse_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DatabaseName types.String `tfsdk:"database_name"` -} - -func NewClickhouseDatabaseResource() resource.Resource { - return &ClickhouseDatabaseResource{} -} - -func (r *ClickhouseDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse_database" -} - -func (r *ClickhouseDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "clickhouse_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "database_name": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `db01` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan ClickhouseDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.DatabaseName.IsNull() || plan.DatabaseName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "database_name is required.") - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - } - identityCodes := []string{ - "databaseName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_database" == "" { - return - } - - instanceUID := strings.TrimSpace(state.ClickhouseID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(state.DatabaseName), - } - identityCodes := []string{ - "databaseName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "databaseName": resources_core.FormatString(state.DatabaseName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_database", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *ClickhouseDatabaseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/120_clickhouse_resource.go b/generated/dev/go/120_clickhouse_resource.go deleted file mode 100644 index 9579b89..0000000 --- a/generated/dev/go/120_clickhouse_resource.go +++ /dev/null @@ -1,628 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Service ID: 120 - -var _ resource.Resource = &ClickhouseResource{} -var _ resource.ResourceWithModifyPlan = &ClickhouseResource{} -var _ resource.ResourceWithImportState = &ClickhouseResource{} - -type ClickhouseResource struct { - client *core.UniversalClient -} - -type ClickhouseModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AppVersion types.String `tfsdk:"app_version"` - ExtBACKUPNUMTORETAIN types.Int64 `tfsdk:"ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n"` - ExtBACKUPSCHEDULE types.String `tfsdk:"ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedCreateKeeper types.Bool `tfsdk:"need_create_keeper"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceCPUKeeper types.Int64 `tfsdk:"resource_c_p_u_keeper"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceInstancesKeeper types.Int64 `tfsdk:"resource_instances_keeper"` - ResourceInstancesShards types.Int64 `tfsdk:"resource_instances_shards"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceMemoryKeeper types.Int64 `tfsdk:"resource_memory_keeper"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewClickhouseResource() resource.Resource { - return &ClickhouseResource{} -} - -func (r *ClickhouseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse" -} - -func (r *ClickhouseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("25.10"), MarkdownDescription: "Версия `clickhouse-server`"}, - "ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(7), MarkdownDescription: "Пример: `7`"}, - "ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("0 0 * * *"), MarkdownDescription: "Принимает формат `CRON`"}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"}, - "need_create_keeper": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Необходим для кластеризации ClickHouse"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Позволяет подключиться извне к ClickHouse"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Пример: `1000`"}, - "resource_c_p_u_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(50), MarkdownDescription: "Пример: `100`"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Пример: `100`"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `3`"}, - "resource_instances_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"}, - "resource_instances_shards": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1536), MarkdownDescription: "Пример: `2048`"}, - "resource_memory_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(152), MarkdownDescription: "Пример: `256`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Кластер Kubernetes в котором будет развёрнуто приложение Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *ClickhouseModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() { - plan.S3Uid = types.StringValue(resolvedS3Uid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - if plan.S3Uid.ValueString() != state.S3Uid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 572: resources_core.FormatString(config.ResourceRealm), - 573: resources_core.FormatString(config.S3Uid), - 574: resources_core.FormatInt64(config.ResourceInstances), - 575: resources_core.FormatInt64(config.ResourceInstancesShards), - 576: resources_core.FormatInt64(config.ResourceCPU), - 577: resources_core.FormatInt64(config.ResourceMemory), - 578: resources_core.FormatString(config.AppVersion), - 579: resources_core.FormatInt64(config.ResourceDisk), - 580: resources_core.FormatBool(config.NeedExternalAddressMaster), - 581: resources_core.FormatString(config.IpSpaceNameMaster), - 582: resources_core.FormatBool(config.NeedCreateKeeper), - 583: resources_core.FormatInt64(config.ResourceCPUKeeper), - 584: resources_core.FormatInt64(config.ResourceMemoryKeeper), - 585: resources_core.FormatInt64(config.ResourceInstancesKeeper), - 586: resources_core.FormatString(config.ExtBACKUPSCHEDULE), - 587: resources_core.FormatInt64(config.ExtBACKUPNUMTORETAIN), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 120, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *ClickhouseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 120, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 572: resources_core.FormatString(data.ResourceRealm), - 573: resources_core.FormatString(data.S3Uid), - 574: resources_core.FormatInt64(data.ResourceInstances), - 575: resources_core.FormatInt64(data.ResourceInstancesShards), - 576: resources_core.FormatInt64(data.ResourceCPU), - 577: resources_core.FormatInt64(data.ResourceMemory), - 578: resources_core.FormatString(data.AppVersion), - 579: resources_core.FormatInt64(data.ResourceDisk), - 580: resources_core.FormatBool(data.NeedExternalAddressMaster), - 581: resources_core.FormatString(data.IpSpaceNameMaster), - 582: resources_core.FormatBool(data.NeedCreateKeeper), - 583: resources_core.FormatInt64(data.ResourceCPUKeeper), - 584: resources_core.FormatInt64(data.ResourceMemoryKeeper), - 585: resources_core.FormatInt64(data.ResourceInstancesKeeper), - 586: resources_core.FormatString(data.ExtBACKUPSCHEDULE), - 587: resources_core.FormatInt64(data.ExtBACKUPNUMTORETAIN), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 120, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 120, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"}, - {Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 120, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"}, - {Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *ClickhouseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseModel - var state ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstancesShards.IsNull() != state.ResourceInstancesShards.IsNull() || plan.ResourceInstancesShards.IsUnknown() != state.ResourceInstancesShards.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstancesShards.IsNull() && !plan.ResourceInstancesShards.IsUnknown() && !state.ResourceInstancesShards.IsNull() && !state.ResourceInstancesShards.IsUnknown() { - if plan.ResourceInstancesShards.ValueInt64() != state.ResourceInstancesShards.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedCreateKeeper.IsNull() != state.NeedCreateKeeper.IsNull() || plan.NeedCreateKeeper.IsUnknown() != state.NeedCreateKeeper.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedCreateKeeper.IsNull() && !plan.NeedCreateKeeper.IsUnknown() && !state.NeedCreateKeeper.IsNull() && !state.NeedCreateKeeper.IsUnknown() { - if plan.NeedCreateKeeper.ValueBool() != state.NeedCreateKeeper.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPUKeeper.IsNull() != state.ResourceCPUKeeper.IsNull() || plan.ResourceCPUKeeper.IsUnknown() != state.ResourceCPUKeeper.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPUKeeper.IsNull() && !plan.ResourceCPUKeeper.IsUnknown() && !state.ResourceCPUKeeper.IsNull() && !state.ResourceCPUKeeper.IsUnknown() { - if plan.ResourceCPUKeeper.ValueInt64() != state.ResourceCPUKeeper.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemoryKeeper.IsNull() != state.ResourceMemoryKeeper.IsNull() || plan.ResourceMemoryKeeper.IsUnknown() != state.ResourceMemoryKeeper.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemoryKeeper.IsNull() && !plan.ResourceMemoryKeeper.IsUnknown() && !state.ResourceMemoryKeeper.IsNull() && !state.ResourceMemoryKeeper.IsUnknown() { - if plan.ResourceMemoryKeeper.ValueInt64() != state.ResourceMemoryKeeper.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstancesKeeper.IsNull() != state.ResourceInstancesKeeper.IsNull() || plan.ResourceInstancesKeeper.IsUnknown() != state.ResourceInstancesKeeper.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstancesKeeper.IsNull() && !plan.ResourceInstancesKeeper.IsUnknown() && !state.ResourceInstancesKeeper.IsNull() && !state.ResourceInstancesKeeper.IsUnknown() { - if plan.ResourceInstancesKeeper.ValueInt64() != state.ResourceInstancesKeeper.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPSCHEDULE.IsNull() != state.ExtBACKUPSCHEDULE.IsNull() || plan.ExtBACKUPSCHEDULE.IsUnknown() != state.ExtBACKUPSCHEDULE.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPSCHEDULE.IsNull() && !plan.ExtBACKUPSCHEDULE.IsUnknown() && !state.ExtBACKUPSCHEDULE.IsNull() && !state.ExtBACKUPSCHEDULE.IsUnknown() { - if plan.ExtBACKUPSCHEDULE.ValueString() != state.ExtBACKUPSCHEDULE.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPNUMTORETAIN.IsNull() != state.ExtBACKUPNUMTORETAIN.IsNull() || plan.ExtBACKUPNUMTORETAIN.IsUnknown() != state.ExtBACKUPNUMTORETAIN.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPNUMTORETAIN.IsNull() && !plan.ExtBACKUPNUMTORETAIN.IsUnknown() && !state.ExtBACKUPNUMTORETAIN.IsNull() && !state.ExtBACKUPNUMTORETAIN.IsUnknown() { - if plan.ExtBACKUPNUMTORETAIN.ValueInt64() != state.ExtBACKUPNUMTORETAIN.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 603: resources_core.FormatInt64(plan.ResourceInstances), - 604: resources_core.FormatInt64(plan.ResourceInstancesShards), - 605: resources_core.FormatInt64(plan.ResourceCPU), - 606: resources_core.FormatInt64(plan.ResourceMemory), - 607: resources_core.FormatString(plan.AppVersion), - 608: resources_core.FormatInt64(plan.ResourceDisk), - 609: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 610: resources_core.FormatString(plan.IpSpaceNameMaster), - 611: resources_core.FormatBool(plan.NeedCreateKeeper), - 612: resources_core.FormatInt64(plan.ResourceCPUKeeper), - 613: resources_core.FormatInt64(plan.ResourceMemoryKeeper), - 614: resources_core.FormatInt64(plan.ResourceInstancesKeeper), - 615: resources_core.FormatString(plan.ExtBACKUPSCHEDULE), - 616: resources_core.FormatInt64(plan.ExtBACKUPNUMTORETAIN), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 120, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"}, - {Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *ClickhouseResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *ClickhouseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/120_clickhouse_user_resource.go b/generated/dev/go/120_clickhouse_user_resource.go deleted file mode 100644 index 30a38bf..0000000 --- a/generated/dev/go/120_clickhouse_user_resource.go +++ /dev/null @@ -1,367 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Subresource: user - -var _ resource.Resource = &ClickhouseUserResource{} - -// ClickhouseUserResource manages a subresource via operations. -type ClickhouseUserResource struct { - client *core.UniversalClient -} - -type ClickhouseUserModel struct { - ID types.String `tfsdk:"id"` - ClickhouseID types.String `tfsdk:"clickhouse_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessHosts types.String `tfsdk:"access_hosts"` - DatabaseName types.String `tfsdk:"database_name"` - Username types.String `tfsdk:"username"` -} - -func NewClickhouseUserResource() resource.Resource { - return &ClickhouseUserResource{} -} - -func (r *ClickhouseUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse_user" -} - -func (r *ClickhouseUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "clickhouse_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_hosts": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("::/0"), MarkdownDescription: "Пример: `::/0` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "database_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[\"database\"]"), MarkdownDescription: "Необходимо указать массив существующих баз Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `myusername` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan ClickhouseUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "accessHosts", - "databaseName", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.ClickhouseID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(state.AccessHosts), - "databaseName": resources_core.FormatString(state.DatabaseName), - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "accessHosts", - "databaseName", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *ClickhouseUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/12_s3_resource.go b/generated/dev/go/12_s3_resource.go deleted file mode 100644 index 3f3b56b..0000000 --- a/generated/dev/go/12_s3_resource.go +++ /dev/null @@ -1,412 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3 -// Service ID: 12 - -var _ resource.Resource = &S3Resource{} -var _ resource.ResourceWithModifyPlan = &S3Resource{} -var _ resource.ResourceWithImportState = &S3Resource{} - -type S3Resource struct { - client *core.UniversalClient -} - -type S3Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DisplayName types.String `tfsdk:"display_name"` - MaxBucketsPerUser types.Int64 `tfsdk:"max_buckets_per_user"` - MaxObjectsPerBucket types.Int64 `tfsdk:"max_objects_per_bucket"` - MaxSizeGbPerUser types.Int64 `tfsdk:"max_size_gb_per_user"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewS3Resource() resource.Resource { - return &S3Resource{} -} - -func (r *S3Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3" -} - -func (r *S3Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "display_name": schema.StringAttribute{Required: true, MarkdownDescription: "Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента Не изменяется после создания."}, - "max_buckets_per_user": schema.Int64Attribute{Optional: true, MarkdownDescription: "Квота на пользователя. Количество бакетов пользователя. Передаём руками"}, - "max_objects_per_bucket": schema.Int64Attribute{Optional: true, MarkdownDescription: "Квота на бакет. Кол-во объектов. Передаём руками"}, - "max_size_gb_per_user": schema.Int64Attribute{Optional: true, MarkdownDescription: "maxSizeGb. Передаём руками"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *S3Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.DisplayName.IsNull() && !plan.DisplayName.IsUnknown() && !state.DisplayName.IsNull() && !state.DisplayName.IsUnknown() { - if plan.DisplayName.ValueString() != state.DisplayName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить display_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.DisplayName.IsNull() || config.DisplayName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "display_name is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 163: resources_core.FormatString(config.ResourceRealm), - 320: resources_core.FormatString(config.DisplayName), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 12, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *S3Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.DisplayName.IsNull() || data.DisplayName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "display_name is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 12, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 163: resources_core.FormatString(data.ResourceRealm), - 320: resources_core.FormatString(data.DisplayName), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 12, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 12, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 12, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *S3Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3Model - var state S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.MaxSizeGbPerUser.IsNull() != state.MaxSizeGbPerUser.IsNull() || plan.MaxSizeGbPerUser.IsUnknown() != state.MaxSizeGbPerUser.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxSizeGbPerUser.IsNull() && !plan.MaxSizeGbPerUser.IsUnknown() && !state.MaxSizeGbPerUser.IsNull() && !state.MaxSizeGbPerUser.IsUnknown() { - if plan.MaxSizeGbPerUser.ValueInt64() != state.MaxSizeGbPerUser.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MaxObjectsPerBucket.IsNull() != state.MaxObjectsPerBucket.IsNull() || plan.MaxObjectsPerBucket.IsUnknown() != state.MaxObjectsPerBucket.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxObjectsPerBucket.IsNull() && !plan.MaxObjectsPerBucket.IsUnknown() && !state.MaxObjectsPerBucket.IsNull() && !state.MaxObjectsPerBucket.IsUnknown() { - if plan.MaxObjectsPerBucket.ValueInt64() != state.MaxObjectsPerBucket.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MaxBucketsPerUser.IsNull() != state.MaxBucketsPerUser.IsNull() || plan.MaxBucketsPerUser.IsUnknown() != state.MaxBucketsPerUser.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxBucketsPerUser.IsNull() && !plan.MaxBucketsPerUser.IsUnknown() && !state.MaxBucketsPerUser.IsNull() && !state.MaxBucketsPerUser.IsUnknown() { - if plan.MaxBucketsPerUser.ValueInt64() != state.MaxBucketsPerUser.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 50: resources_core.FormatInt64(plan.MaxSizeGbPerUser), - 51: resources_core.FormatInt64(plan.MaxObjectsPerBucket), - 52: resources_core.FormatInt64(plan.MaxBucketsPerUser), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 12, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *S3Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *S3Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/12_s3_sub_user_resource.go b/generated/dev/go/12_s3_sub_user_resource.go deleted file mode 100644 index c9d01a6..0000000 --- a/generated/dev/go/12_s3_sub_user_resource.go +++ /dev/null @@ -1,362 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3 -// Subresource: sub_user - -var _ resource.Resource = &S3SubUserResource{} - -// S3SubUserResource manages a subresource via operations. -type S3SubUserResource struct { - client *core.UniversalClient -} - -type S3SubUserModel struct { - ID types.String `tfsdk:"id"` - S3ID types.String `tfsdk:"s3_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - SubUserAccess types.String `tfsdk:"sub_user_access"` - SubUserName types.String `tfsdk:"sub_user_name"` -} - -func NewS3SubUserResource() resource.Resource { - return &S3SubUserResource{} -} - -func (r *S3SubUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3_sub_user" -} - -func (r *S3SubUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "s3_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "sub_user_access": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "sub_user_name": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3SubUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan S3SubUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.SubUserAccess.IsNull() || plan.SubUserAccess.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "sub_user_access is required.") - return - } - if plan.SubUserName.IsNull() || plan.SubUserName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "sub_user_name is required.") - return - } - - instanceUID := strings.TrimSpace(plan.S3ID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - "subUserName": resources_core.FormatString(plan.SubUserName), - } - identityCodes := []string{ - "subUserAccess", - "subUserName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("sub_user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "subUserName": resources_core.FormatString(plan.SubUserName), - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_sub_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_sub_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *S3SubUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3SubUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3SubUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.S3ID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - "subUserName": resources_core.FormatString(plan.SubUserName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *S3SubUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_sub_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.S3ID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(state.SubUserAccess), - "subUserName": resources_core.FormatString(state.SubUserName), - } - identityCodes := []string{ - "subUserAccess", - "subUserName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("sub_user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "subUserName": resources_core.FormatString(state.SubUserName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_sub_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *S3SubUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/13_s3bucket_resource.go b/generated/dev/go/13_s3bucket_resource.go deleted file mode 100644 index 06bd07d..0000000 --- a/generated/dev/go/13_s3bucket_resource.go +++ /dev/null @@ -1,450 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3bucket -// Service ID: 13 - -var _ resource.Resource = &S3bucketResource{} -var _ resource.ResourceWithModifyPlan = &S3bucketResource{} -var _ resource.ResourceWithImportState = &S3bucketResource{} - -type S3bucketResource struct { - client *core.UniversalClient -} - -type S3bucketModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - BucketName types.String `tfsdk:"bucket_name"` - CorsAll types.Bool `tfsdk:"cors_all"` - ListAll types.Bool `tfsdk:"list_all"` - MaxSize types.String `tfsdk:"max_size"` - Placement types.String `tfsdk:"placement"` - ReadAll types.Bool `tfsdk:"read_all"` - S3UserUid types.String `tfsdk:"s3_user_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewS3bucketResource() resource.Resource { - return &S3bucketResource{} -} - -func (r *S3bucketResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3bucket" -} - -func (r *S3bucketResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "bucket_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя бакета s3 Не изменяется после создания."}, - "cors_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS Не изменяется после создания."}, - "list_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. Не изменяется после создания."}, - "max_size": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("-1"), MarkdownDescription: "Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes Не изменяется после создания."}, - "placement": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("HOT"), MarkdownDescription: "Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения Не изменяется после создания."}, - "read_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. Не изменяется после создания."}, - "s3_user_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UID Корневой услуги S3. На основе него будет создан бакет. Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3bucketResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *S3bucketModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3UserUid.IsNull() && !plan.S3UserUid.IsUnknown() { - resolvedS3UserUid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3UserUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_user_uid", err.Error()) - } else if resolvedS3UserUid != "" && resolvedS3UserUid != plan.S3UserUid.ValueString() { - plan.S3UserUid = types.StringValue(resolvedS3UserUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.BucketName.IsNull() && !plan.BucketName.IsUnknown() && !state.BucketName.IsNull() && !state.BucketName.IsUnknown() { - if plan.BucketName.ValueString() != state.BucketName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить bucket_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.CorsAll.IsNull() && !plan.CorsAll.IsUnknown() && !state.CorsAll.IsNull() && !state.CorsAll.IsUnknown() { - if plan.CorsAll.ValueBool() != state.CorsAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить cors_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ListAll.IsNull() && !plan.ListAll.IsUnknown() && !state.ListAll.IsNull() && !state.ListAll.IsUnknown() { - if plan.ListAll.ValueBool() != state.ListAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить list_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MaxSize.IsNull() && !plan.MaxSize.IsUnknown() && !state.MaxSize.IsNull() && !state.MaxSize.IsUnknown() { - if plan.MaxSize.ValueString() != state.MaxSize.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить max_size", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Placement.IsNull() && !plan.Placement.IsUnknown() && !state.Placement.IsNull() && !state.Placement.IsUnknown() { - if plan.Placement.ValueString() != state.Placement.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить placement", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ReadAll.IsNull() && !plan.ReadAll.IsUnknown() && !state.ReadAll.IsNull() && !state.ReadAll.IsUnknown() { - if plan.ReadAll.ValueBool() != state.ReadAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить read_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3UserUid.IsNull() && !plan.S3UserUid.IsUnknown() && !state.S3UserUid.IsNull() && !state.S3UserUid.IsUnknown() { - if plan.S3UserUid.ValueString() != state.S3UserUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_user_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.BucketName.IsNull() || config.BucketName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "bucket_name is required.") - return - } - if config.S3UserUid.IsNull() || config.S3UserUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_user_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3UserUid.IsNull() && !config.S3UserUid.IsUnknown() { - resolvedS3UserUid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3UserUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_user_uid", err.Error()) - } else if resolvedS3UserUid != "" && resolvedS3UserUid != config.S3UserUid.ValueString() { - config.S3UserUid = types.StringValue(resolvedS3UserUid) - } - } - params := map[int]string{ - 124: resources_core.FormatString(config.S3UserUid), - 125: resources_core.FormatString(config.BucketName), - 126: resources_core.FormatString(config.MaxSize), - 127: resources_core.FormatBool(config.ReadAll), - 128: resources_core.FormatBool(config.ListAll), - 129: resources_core.FormatBool(config.CorsAll), - 130: resources_core.FormatString(config.Placement), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 13, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *S3bucketResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.BucketName.IsNull() || data.BucketName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "bucket_name is required.") - return - } - if data.S3UserUid.IsNull() || data.S3UserUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_user_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 13, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 124: resources_core.FormatString(data.S3UserUid), - 125: resources_core.FormatString(data.BucketName), - 126: resources_core.FormatString(data.MaxSize), - 127: resources_core.FormatBool(data.ReadAll), - 128: resources_core.FormatBool(data.ListAll), - 129: resources_core.FormatBool(data.CorsAll), - 130: resources_core.FormatString(data.Placement), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 13, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 13, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3bucketResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 13, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *S3bucketResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3bucketModel - var state S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 13, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3bucketResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *S3bucketResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *S3bucketResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/149_valo_tenant_resource.go b/generated/dev/go/149_valo_tenant_resource.go deleted file mode 100644 index 2e2a5c7..0000000 --- a/generated/dev/go/149_valo_tenant_resource.go +++ /dev/null @@ -1,409 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: valo_tenant -// Service ID: 149 - -var _ resource.Resource = &ValoTenantResource{} -var _ resource.ResourceWithModifyPlan = &ValoTenantResource{} -var _ resource.ResourceWithImportState = &ValoTenantResource{} - -type ValoTenantResource struct { - client *core.UniversalClient -} - -type ValoTenantModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Storage types.Int64 `tfsdk:"s3_storage"` - ValoOptions types.String `tfsdk:"valo_options"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewValoTenantResource() resource.Resource { - return &ValoTenantResource{} -} - -func (r *ValoTenantResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_valo_tenant" -} - -func (r *ValoTenantResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Будет добавлено в зону valo.ngcloud.ru Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "s3_storage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Параметр указывается в `Gb`"}, - "valo_options": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{}")}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ValoTenantResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *ValoTenantModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() || config.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 655: resources_core.FormatString(config.ResourceRealm), - 656: resources_core.FormatString(config.Domain), - 657: resources_core.FormatString(config.ValoOptions), - 658: resources_core.FormatInt64(config.S3Storage), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 149, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *ValoTenantResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 149, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 655: resources_core.FormatString(data.ResourceRealm), - 656: resources_core.FormatString(data.Domain), - 657: resources_core.FormatString(data.ValoOptions), - 658: resources_core.FormatInt64(data.S3Storage), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 149, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 149, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ValoTenantResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 149, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *ValoTenantResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ValoTenantModel - var state ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ValoOptions.IsNull() != state.ValoOptions.IsNull() || plan.ValoOptions.IsUnknown() != state.ValoOptions.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ValoOptions.IsNull() && !plan.ValoOptions.IsUnknown() && !state.ValoOptions.IsNull() && !state.ValoOptions.IsUnknown() { - if plan.ValoOptions.ValueString() != state.ValoOptions.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.S3Storage.IsNull() != state.S3Storage.IsNull() || plan.S3Storage.IsUnknown() != state.S3Storage.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.S3Storage.IsNull() && !plan.S3Storage.IsUnknown() && !state.S3Storage.IsNull() && !state.S3Storage.IsUnknown() { - if plan.S3Storage.ValueInt64() != state.S3Storage.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 659: resources_core.FormatString(plan.ValoOptions), - 660: resources_core.FormatInt64(plan.S3Storage), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 149, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ValoTenantResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *ValoTenantResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *ValoTenantResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/150_k8s_sthutrval_cluster_reconcile_action.go b/generated/dev/go/150_k8s_sthutrval_cluster_reconcile_action.go deleted file mode 100644 index b82d8d6..0000000 --- a/generated/dev/go/150_k8s_sthutrval_cluster_reconcile_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_sthutrval_cluster -// Action: reconcile - -var _ resource.Resource = &K8sSthutrvalClusterReconcileResource{} - -// K8sSthutrvalClusterReconcileResource triggers a one-time action. -type K8sSthutrvalClusterReconcileResource struct { - client *core.UniversalClient -} - -type K8sSthutrvalClusterReconcileModel struct { - ID types.String `tfsdk:"id"` - K8sSthutrvalClusterID types.String `tfsdk:"k8s_sthutrval_cluster_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewK8sSthutrvalClusterReconcileResource() resource.Resource { - return &K8sSthutrvalClusterReconcileResource{} -} - -func (r *K8sSthutrvalClusterReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_sthutrval_cluster_reconcile" -} - -func (r *K8sSthutrvalClusterReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_sthutrval_cluster_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sSthutrvalClusterReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sSthutrvalClusterReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sSthutrvalClusterReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sSthutrvalClusterReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sSthutrvalClusterReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/150_k8s_sthutrval_cluster_resource.go b/generated/dev/go/150_k8s_sthutrval_cluster_resource.go deleted file mode 100644 index d77b29c..0000000 --- a/generated/dev/go/150_k8s_sthutrval_cluster_resource.go +++ /dev/null @@ -1,439 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_sthutrval_cluster -// Service ID: 150 - -var _ resource.Resource = &K8sSthutrvalClusterResource{} -var _ resource.ResourceWithModifyPlan = &K8sSthutrvalClusterResource{} -var _ resource.ResourceWithImportState = &K8sSthutrvalClusterResource{} - -type K8sSthutrvalClusterResource struct { - client *core.UniversalClient -} - -type K8sSthutrvalClusterModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - ControlPlaneConfiguration types.String `tfsdk:"control_plane_configuration"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - WorkerConfiguration types.String `tfsdk:"worker_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewK8sSthutrvalClusterResource() resource.Resource { - return &K8sSthutrvalClusterResource{} -} - -func (r *K8sSthutrvalClusterResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_sthutrval_cluster" -} - -func (r *K8sSthutrvalClusterResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "control_plane_configuration": schema.StringAttribute{Required: true}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "worker_configuration": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]")}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sSthutrvalClusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - if plan.StartupConfiguration.ValueString() != state.StartupConfiguration.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() || config.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.ClusterConfiguration.IsNull() || config.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ControlPlaneConfiguration.IsNull() || config.ControlPlaneConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "control_plane_configuration is required.") - return - } - if config.StartupConfiguration.IsNull() || config.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 750: resources_core.FormatString(config.StartupConfiguration), - 751: resources_core.FormatString(config.ControlPlaneConfiguration), - 752: resources_core.FormatString(config.WorkerConfiguration), - 753: resources_core.FormatString(config.AccessConfiguration), - 755: resources_core.FormatString(config.ClusterConfiguration), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 150, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *K8sSthutrvalClusterResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.ControlPlaneConfiguration.IsNull() || data.ControlPlaneConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "control_plane_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 150, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 750: resources_core.FormatString(data.StartupConfiguration), - 751: resources_core.FormatString(data.ControlPlaneConfiguration), - 752: resources_core.FormatString(data.WorkerConfiguration), - 753: resources_core.FormatString(data.AccessConfiguration), - 755: resources_core.FormatString(data.ClusterConfiguration), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 150, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 150, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "controlPlaneConfiguration", Field: "ControlPlaneConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - {Code: "workerConfiguration", Field: "WorkerConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 150, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "controlPlaneConfiguration", Field: "ControlPlaneConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - {Code: "workerConfiguration", Field: "WorkerConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *K8sSthutrvalClusterResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sSthutrvalClusterModel - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if plan.ClusterConfiguration.ValueString() != state.ClusterConfiguration.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ControlPlaneConfiguration.IsNull() != state.ControlPlaneConfiguration.IsNull() || plan.ControlPlaneConfiguration.IsUnknown() != state.ControlPlaneConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ControlPlaneConfiguration.IsNull() && !plan.ControlPlaneConfiguration.IsUnknown() && !state.ControlPlaneConfiguration.IsNull() && !state.ControlPlaneConfiguration.IsUnknown() { - if plan.ControlPlaneConfiguration.ValueString() != state.ControlPlaneConfiguration.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.WorkerConfiguration.IsNull() != state.WorkerConfiguration.IsNull() || plan.WorkerConfiguration.IsUnknown() != state.WorkerConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.WorkerConfiguration.IsNull() && !plan.WorkerConfiguration.IsUnknown() && !state.WorkerConfiguration.IsNull() && !state.WorkerConfiguration.IsUnknown() { - if plan.WorkerConfiguration.ValueString() != state.WorkerConfiguration.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessConfiguration.IsNull() != state.AccessConfiguration.IsNull() || plan.AccessConfiguration.IsUnknown() != state.AccessConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - if plan.AccessConfiguration.ValueString() != state.AccessConfiguration.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 756: resources_core.FormatString(plan.ClusterConfiguration), - 757: resources_core.FormatString(plan.ControlPlaneConfiguration), - 758: resources_core.FormatString(plan.WorkerConfiguration), - 759: resources_core.FormatString(plan.AccessConfiguration), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 150, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "controlPlaneConfiguration", Field: "ControlPlaneConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - {Code: "workerConfiguration", Field: "WorkerConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *K8sSthutrvalClusterResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *K8sSthutrvalClusterResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/150_k8s_sthutrval_cluster_update_secrets_action.go b/generated/dev/go/150_k8s_sthutrval_cluster_update_secrets_action.go deleted file mode 100644 index b019fdb..0000000 --- a/generated/dev/go/150_k8s_sthutrval_cluster_update_secrets_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_sthutrval_cluster -// Action: update_secrets - -var _ resource.Resource = &K8sSthutrvalClusterUpdateSecretsResource{} - -// K8sSthutrvalClusterUpdateSecretsResource triggers a one-time action. -type K8sSthutrvalClusterUpdateSecretsResource struct { - client *core.UniversalClient -} - -type K8sSthutrvalClusterUpdateSecretsModel struct { - ID types.String `tfsdk:"id"` - K8sSthutrvalClusterID types.String `tfsdk:"k8s_sthutrval_cluster_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewK8sSthutrvalClusterUpdateSecretsResource() resource.Resource { - return &K8sSthutrvalClusterUpdateSecretsResource{} -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_sthutrval_cluster_update_secrets" -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_sthutrval_cluster_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sSthutrvalClusterUpdateSecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "update_secrets", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "update_secrets", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sSthutrvalClusterUpdateSecretsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sSthutrvalClusterUpdateSecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "update_secrets", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "update_secrets", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_kv_resource.go b/generated/dev/go/151_k8s_openbao_kv_resource.go deleted file mode 100644 index 7e46c20..0000000 --- a/generated/dev/go/151_k8s_openbao_kv_resource.go +++ /dev/null @@ -1,347 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Subresource: kv - -var _ resource.Resource = &K8sOpenbaoKvResource{} - -// K8sOpenbaoKvResource manages a subresource via operations. -type K8sOpenbaoKvResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoKvModel struct { - ID types.String `tfsdk:"id"` - K8sOpenbaoID types.String `tfsdk:"k8s_openbao_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - KvName types.String `tfsdk:"kv_name"` -} - -func NewK8sOpenbaoKvResource() resource.Resource { - return &K8sOpenbaoKvResource{} -} - -func (r *K8sOpenbaoKvResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao_kv" -} - -func (r *K8sOpenbaoKvResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_openbao_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "kv_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("kvname-"), MarkdownDescription: "Будет создан `v2 тип движка`

Уникальное в рамках услуги Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoKvResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sOpenbaoKvModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - } - identityCodes := []string{ - "kvName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("kv", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "kv", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_kv", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_kv", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "kv", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "kv", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "kv", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoKvResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoKvModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoKvResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoKvModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state K8sOpenbaoKvModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "kv", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoKvResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sOpenbaoKvModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_kv" == "" { - return - } - - instanceUID := strings.TrimSpace(state.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "kvName": resources_core.FormatString(state.KvName), - } - identityCodes := []string{ - "kvName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("kv", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "kvName": resources_core.FormatString(state.KvName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_kv", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *K8sOpenbaoKvResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_policy_resource.go b/generated/dev/go/151_k8s_openbao_policy_resource.go deleted file mode 100644 index 1c8e3c4..0000000 --- a/generated/dev/go/151_k8s_openbao_policy_resource.go +++ /dev/null @@ -1,359 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Subresource: policy - -var _ resource.Resource = &K8sOpenbaoPolicyResource{} - -// K8sOpenbaoPolicyResource manages a subresource via operations. -type K8sOpenbaoPolicyResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoPolicyModel struct { - ID types.String `tfsdk:"id"` - K8sOpenbaoID types.String `tfsdk:"k8s_openbao_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - PolicyName types.String `tfsdk:"policy_name"` - PolicySettings types.String `tfsdk:"policy_settings"` -} - -func NewK8sOpenbaoPolicyResource() resource.Resource { - return &K8sOpenbaoPolicyResource{} -} - -func (r *K8sOpenbaoPolicyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao_policy" -} - -func (r *K8sOpenbaoPolicyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_openbao_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "policy_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("policy-"), MarkdownDescription: "Сделано для дальнейшего удобного использования Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "policy_settings": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoPolicyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sOpenbaoPolicyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.PolicySettings.IsNull() || plan.PolicySettings.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "policy_settings is required.") - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "policyName": resources_core.FormatString(plan.PolicyName), - "policySettings": resources_core.FormatString(plan.PolicySettings), - } - identityCodes := []string{ - "policyName", - "policySettings", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("policy", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "policy", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "policySettings": resources_core.FormatString(plan.PolicySettings), - "policyName": resources_core.FormatString(plan.PolicyName), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_policy", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_policy", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "policy", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "policy", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "policy", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoPolicyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoPolicyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoPolicyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoPolicyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state K8sOpenbaoPolicyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "policyName": resources_core.FormatString(plan.PolicyName), - "policySettings": resources_core.FormatString(plan.PolicySettings), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "policy", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoPolicyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sOpenbaoPolicyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_policy" == "" { - return - } - - instanceUID := strings.TrimSpace(state.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "policyName": resources_core.FormatString(state.PolicyName), - "policySettings": resources_core.FormatString(state.PolicySettings), - } - identityCodes := []string{ - "policyName", - "policySettings", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("policy", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "policyName": resources_core.FormatString(state.PolicyName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_policy", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *K8sOpenbaoPolicyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_reconcile_action.go b/generated/dev/go/151_k8s_openbao_reconcile_action.go deleted file mode 100644 index 74109bb..0000000 --- a/generated/dev/go/151_k8s_openbao_reconcile_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Action: reconcile - -var _ resource.Resource = &K8sOpenbaoReconcileResource{} - -// K8sOpenbaoReconcileResource triggers a one-time action. -type K8sOpenbaoReconcileResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoReconcileModel struct { - ID types.String `tfsdk:"id"` - K8sOpenbaoID types.String `tfsdk:"k8s_openbao_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewK8sOpenbaoReconcileResource() resource.Resource { - return &K8sOpenbaoReconcileResource{} -} - -func (r *K8sOpenbaoReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao_reconcile" -} - -func (r *K8sOpenbaoReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_openbao_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sOpenbaoReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sOpenbaoReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_recovery_secrets_action.go b/generated/dev/go/151_k8s_openbao_recovery_secrets_action.go deleted file mode 100644 index 35d0782..0000000 --- a/generated/dev/go/151_k8s_openbao_recovery_secrets_action.go +++ /dev/null @@ -1,162 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Action: recovery_secrets - -var _ resource.Resource = &K8sOpenbaoRecoverySecretsResource{} - -// K8sOpenbaoRecoverySecretsResource triggers a one-time action. -type K8sOpenbaoRecoverySecretsResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoRecoverySecretsModel struct { - ID types.String `tfsdk:"id"` - K8sOpenbaoID types.String `tfsdk:"k8s_openbao_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - KvName types.String `tfsdk:"kv_name"` - SecretPath types.String `tfsdk:"secret_path"` - SecretVersion types.String `tfsdk:"secret_version"` -} - -func NewK8sOpenbaoRecoverySecretsResource() resource.Resource { - return &K8sOpenbaoRecoverySecretsResource{} -} - -func (r *K8sOpenbaoRecoverySecretsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao_recovery_secrets" -} - -func (r *K8sOpenbaoRecoverySecretsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_openbao_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "kv_name": schema.StringAttribute{Required: true, MarkdownDescription: "Выберите из списка"}, - "secret_path": schema.StringAttribute{Required: true, MarkdownDescription: "Выберите из списка"}, - "secret_version": schema.StringAttribute{Required: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoRecoverySecretsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sOpenbaoRecoverySecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.KvName.IsNull() || plan.KvName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kv_name is required.") - return - } - if plan.SecretPath.IsNull() || plan.SecretPath.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "secret_path is required.") - return - } - if plan.SecretVersion.IsNull() || plan.SecretVersion.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "secret_version is required.") - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - "secretPath": resources_core.FormatString(plan.SecretPath), - "secretVersion": resources_core.FormatString(plan.SecretVersion), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "recovery_secrets", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "recovery_secrets", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoRecoverySecretsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoRecoverySecretsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoRecoverySecretsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoRecoverySecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - "secretPath": resources_core.FormatString(plan.SecretPath), - "secretVersion": resources_core.FormatString(plan.SecretVersion), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "recovery_secrets", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "recovery_secrets", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoRecoverySecretsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sOpenbaoRecoverySecretsResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_resource.go b/generated/dev/go/151_k8s_openbao_resource.go deleted file mode 100644 index c593cd6..0000000 --- a/generated/dev/go/151_k8s_openbao_resource.go +++ /dev/null @@ -1,452 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Service ID: 151 - -var _ resource.Resource = &K8sOpenbaoResource{} -var _ resource.ResourceWithModifyPlan = &K8sOpenbaoResource{} -var _ resource.ResourceWithImportState = &K8sOpenbaoResource{} - -type K8sOpenbaoResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AppVersion types.String `tfsdk:"app_version"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewK8sOpenbaoResource() resource.Resource { - return &K8sOpenbaoResource{} -} - -func (r *K8sOpenbaoResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao" -} - -func (r *K8sOpenbaoResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("2.4.4"), MarkdownDescription: "Выбрать из списка"}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("bao-"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Пример: `500`"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Пример: `10`"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(3), MarkdownDescription: "Пример: `3`"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Кластер Kubernetes в котором будет развёрнуто приложение Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *K8sOpenbaoModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *K8sOpenbaoModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan K8sOpenbaoModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 663: resources_core.FormatString(config.ResourceRealm), - 664: resources_core.FormatInt64(config.ResourceCPU), - 665: resources_core.FormatInt64(config.ResourceInstances), - 666: resources_core.FormatInt64(config.ResourceMemory), - 667: resources_core.FormatInt64(config.ResourceDisk), - 668: resources_core.FormatString(config.AppVersion), - 669: resources_core.FormatString(config.Domain), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 151, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *K8sOpenbaoResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data K8sOpenbaoModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 151, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 663: resources_core.FormatString(data.ResourceRealm), - 664: resources_core.FormatInt64(data.ResourceCPU), - 665: resources_core.FormatInt64(data.ResourceInstances), - 666: resources_core.FormatInt64(data.ResourceMemory), - 667: resources_core.FormatInt64(data.ResourceDisk), - 668: resources_core.FormatString(data.AppVersion), - 669: resources_core.FormatString(data.Domain), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 151, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 151, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 151, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *K8sOpenbaoResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoModel - var state K8sOpenbaoModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 670: resources_core.FormatInt64(plan.ResourceInstances), - 671: resources_core.FormatInt64(plan.ResourceCPU), - 672: resources_core.FormatInt64(plan.ResourceMemory), - 673: resources_core.FormatInt64(plan.ResourceDisk), - 674: resources_core.FormatString(plan.AppVersion), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 151, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sOpenbaoModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *K8sOpenbaoResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *K8sOpenbaoResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_restart_action.go b/generated/dev/go/151_k8s_openbao_restart_action.go deleted file mode 100644 index b2f6d0e..0000000 --- a/generated/dev/go/151_k8s_openbao_restart_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Action: restart - -var _ resource.Resource = &K8sOpenbaoRestartResource{} - -// K8sOpenbaoRestartResource triggers a one-time action. -type K8sOpenbaoRestartResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoRestartModel struct { - ID types.String `tfsdk:"id"` - K8sOpenbaoID types.String `tfsdk:"k8s_openbao_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewK8sOpenbaoRestartResource() resource.Resource { - return &K8sOpenbaoRestartResource{} -} - -func (r *K8sOpenbaoRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao_restart" -} - -func (r *K8sOpenbaoRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_openbao_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sOpenbaoRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoRestartModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sOpenbaoRestartResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_secrets_resource.go b/generated/dev/go/151_k8s_openbao_secrets_resource.go deleted file mode 100644 index 2f499a3..0000000 --- a/generated/dev/go/151_k8s_openbao_secrets_resource.go +++ /dev/null @@ -1,372 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Subresource: secrets - -var _ resource.Resource = &K8sOpenbaoSecretsResource{} - -// K8sOpenbaoSecretsResource manages a subresource via operations. -type K8sOpenbaoSecretsResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoSecretsModel struct { - ID types.String `tfsdk:"id"` - K8sOpenbaoID types.String `tfsdk:"k8s_openbao_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - KvName types.String `tfsdk:"kv_name"` - SecretData types.String `tfsdk:"secret_data"` - SecretPath types.String `tfsdk:"secret_path"` -} - -func NewK8sOpenbaoSecretsResource() resource.Resource { - return &K8sOpenbaoSecretsResource{} -} - -func (r *K8sOpenbaoSecretsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao_secrets" -} - -func (r *K8sOpenbaoSecretsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_openbao_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "kv_name": schema.StringAttribute{Required: true, MarkdownDescription: "Выберите из списка Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "secret_data": schema.StringAttribute{Required: true, MarkdownDescription: "Хотя бы один секрет необходимо добавить Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "secret_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("path/to/mysecret"), MarkdownDescription: "Пример: `path` или `road/to/path` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoSecretsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sOpenbaoSecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.KvName.IsNull() || plan.KvName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kv_name is required.") - return - } - if plan.SecretData.IsNull() || plan.SecretData.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "secret_data is required.") - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - "secretData": resources_core.FormatString(plan.SecretData), - "secretPath": resources_core.FormatString(plan.SecretPath), - } - identityCodes := []string{ - "kvName", - "secretData", - "secretPath", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("secrets", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "secrets", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - "secretPath": resources_core.FormatString(plan.SecretPath), - "secretData": resources_core.FormatString(plan.SecretData), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_secrets", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_secrets", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "secrets", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "secrets", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "secrets", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoSecretsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoSecretsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoSecretsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoSecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state K8sOpenbaoSecretsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - "secretData": resources_core.FormatString(plan.SecretData), - "secretPath": resources_core.FormatString(plan.SecretPath), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "secrets", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoSecretsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sOpenbaoSecretsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_secrets" == "" { - return - } - - instanceUID := strings.TrimSpace(state.K8sOpenbaoID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "kvName": resources_core.FormatString(state.KvName), - "secretData": resources_core.FormatString(state.SecretData), - "secretPath": resources_core.FormatString(state.SecretPath), - } - identityCodes := []string{ - "kvName", - "secretData", - "secretPath", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("secrets", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "kvName": resources_core.FormatString(state.KvName), - "secretPath": resources_core.FormatString(state.SecretPath), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_secrets", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *K8sOpenbaoSecretsResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_update_policy_action.go b/generated/dev/go/151_k8s_openbao_update_policy_action.go deleted file mode 100644 index e8c698f..0000000 --- a/generated/dev/go/151_k8s_openbao_update_policy_action.go +++ /dev/null @@ -1,154 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Action: update_policy - -var _ resource.Resource = &K8sOpenbaoUpdatePolicyResource{} - -// K8sOpenbaoUpdatePolicyResource triggers a one-time action. -type K8sOpenbaoUpdatePolicyResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoUpdatePolicyModel struct { - ID types.String `tfsdk:"id"` - K8sOpenbaoID types.String `tfsdk:"k8s_openbao_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - PolicyName types.String `tfsdk:"policy_name"` - PolicySettings types.String `tfsdk:"policy_settings"` -} - -func NewK8sOpenbaoUpdatePolicyResource() resource.Resource { - return &K8sOpenbaoUpdatePolicyResource{} -} - -func (r *K8sOpenbaoUpdatePolicyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao_update_policy" -} - -func (r *K8sOpenbaoUpdatePolicyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_openbao_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "policy_name": schema.StringAttribute{Required: true}, - "policy_settings": schema.StringAttribute{Required: true, MarkdownDescription: "Производится полная перезапись политики!"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoUpdatePolicyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sOpenbaoUpdatePolicyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.PolicyName.IsNull() || plan.PolicyName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "policy_name is required.") - return - } - if plan.PolicySettings.IsNull() || plan.PolicySettings.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "policy_settings is required.") - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "policyName": resources_core.FormatString(plan.PolicyName), - "policySettings": resources_core.FormatString(plan.PolicySettings), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "update_policy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "update_policy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoUpdatePolicyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoUpdatePolicyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoUpdatePolicyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoUpdatePolicyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "policyName": resources_core.FormatString(plan.PolicyName), - "policySettings": resources_core.FormatString(plan.PolicySettings), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "update_policy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "update_policy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoUpdatePolicyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sOpenbaoUpdatePolicyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/151_k8s_openbao_update_secrets_action.go b/generated/dev/go/151_k8s_openbao_update_secrets_action.go deleted file mode 100644 index 66ace51..0000000 --- a/generated/dev/go/151_k8s_openbao_update_secrets_action.go +++ /dev/null @@ -1,166 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_openbao -// Action: update_secrets - -var _ resource.Resource = &K8sOpenbaoUpdateSecretsResource{} - -// K8sOpenbaoUpdateSecretsResource triggers a one-time action. -type K8sOpenbaoUpdateSecretsResource struct { - client *core.UniversalClient -} - -type K8sOpenbaoUpdateSecretsModel struct { - ID types.String `tfsdk:"id"` - K8sOpenbaoID types.String `tfsdk:"k8s_openbao_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - KvName types.String `tfsdk:"kv_name"` - SecretPath types.String `tfsdk:"secret_path"` - NeedFullUpdateSecret types.Bool `tfsdk:"need_full_update_secret"` - SecretData types.String `tfsdk:"secret_data"` -} - -func NewK8sOpenbaoUpdateSecretsResource() resource.Resource { - return &K8sOpenbaoUpdateSecretsResource{} -} - -func (r *K8sOpenbaoUpdateSecretsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_openbao_update_secrets" -} - -func (r *K8sOpenbaoUpdateSecretsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_openbao_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "kv_name": schema.StringAttribute{Required: true, MarkdownDescription: "Выберите из списка"}, - "secret_path": schema.StringAttribute{Required: true, MarkdownDescription: "Выберите из списка"}, - "need_full_update_secret": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Если выбрать `true`, будет создана новая версия секрета `с нуля`
Если выбрать `false`, будет создана новая версия секрета с данными прошлой ревизии, а переданные данные в операции либо будут модифицированы, либо будут добавлены"}, - "secret_data": schema.StringAttribute{Required: true, MarkdownDescription: "Хотя бы один секрет необходимо добавить"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sOpenbaoUpdateSecretsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sOpenbaoUpdateSecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.KvName.IsNull() || plan.KvName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kv_name is required.") - return - } - if plan.SecretPath.IsNull() || plan.SecretPath.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "secret_path is required.") - return - } - if plan.SecretData.IsNull() || plan.SecretData.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "secret_data is required.") - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - "secretPath": resources_core.FormatString(plan.SecretPath), - "needFullUpdateSecret": resources_core.FormatBool(plan.NeedFullUpdateSecret), - "secretData": resources_core.FormatString(plan.SecretData), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "update_secrets", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "update_secrets", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoUpdateSecretsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sOpenbaoUpdateSecretsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sOpenbaoUpdateSecretsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sOpenbaoUpdateSecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sOpenbaoID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "kvName": resources_core.FormatString(plan.KvName), - "secretPath": resources_core.FormatString(plan.SecretPath), - "needFullUpdateSecret": resources_core.FormatBool(plan.NeedFullUpdateSecret), - "secretData": resources_core.FormatString(plan.SecretData), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "update_secrets", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "update_secrets", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sOpenbaoUpdateSecretsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sOpenbaoUpdateSecretsResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/153_nifi_resource.go b/generated/dev/go/153_nifi_resource.go deleted file mode 100644 index 67a3c9c..0000000 --- a/generated/dev/go/153_nifi_resource.go +++ /dev/null @@ -1,449 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nifi -// Service ID: 153 - -var _ resource.Resource = &NifiResource{} -var _ resource.ResourceWithModifyPlan = &NifiResource{} -var _ resource.ResourceWithImportState = &NifiResource{} - -type NifiResource struct { - client *core.UniversalClient -} - -type NifiModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AppVersion types.String `tfsdk:"app_version"` - Domain types.String `tfsdk:"domain"` - JdbcDrivers types.String `tfsdk:"jdbc_drivers"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNifiResource() resource.Resource { - return &NifiResource{} -} - -func (r *NifiResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nifi" -} - -func (r *NifiResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("2.6.0"), MarkdownDescription: "Выбрать из списка Не изменяется после создания."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("nifi-"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "jdbc_drivers": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `https://jdbc.postgresql.org/download/postgresql-42.7.8.jar` Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(2000), MarkdownDescription: "Пример: `2000` Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Пример: `10` Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1` Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(4096), MarkdownDescription: "Пример: `2048` Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Кластер Kubernetes в котором будет развёрнуто приложение Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NifiResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NifiModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить app_version", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.JdbcDrivers.IsNull() && !plan.JdbcDrivers.IsUnknown() && !state.JdbcDrivers.IsNull() && !state.JdbcDrivers.IsUnknown() { - if plan.JdbcDrivers.ValueString() != state.JdbcDrivers.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить jdbc_drivers", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.JdbcDrivers.IsNull() || config.JdbcDrivers.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "jdbc_drivers is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 711: resources_core.FormatString(config.Domain), - 712: resources_core.FormatInt64(config.ResourceCPU), - 713: resources_core.FormatInt64(config.ResourceMemory), - 714: resources_core.FormatInt64(config.ResourceInstances), - 715: resources_core.FormatInt64(config.ResourceDisk), - 716: resources_core.FormatString(config.AppVersion), - 717: resources_core.FormatString(config.ResourceRealm), - 718: resources_core.FormatString(config.JdbcDrivers), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 153, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NifiResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.JdbcDrivers.IsNull() || data.JdbcDrivers.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "jdbc_drivers is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 153, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 711: resources_core.FormatString(data.Domain), - 712: resources_core.FormatInt64(data.ResourceCPU), - 713: resources_core.FormatInt64(data.ResourceMemory), - 714: resources_core.FormatInt64(data.ResourceInstances), - 715: resources_core.FormatInt64(data.ResourceDisk), - 716: resources_core.FormatString(data.AppVersion), - 717: resources_core.FormatString(data.ResourceRealm), - 718: resources_core.FormatString(data.JdbcDrivers), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 153, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 153, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jdbcDrivers", Field: "JdbcDrivers", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NifiResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 153, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jdbcDrivers", Field: "JdbcDrivers", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NifiResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NifiModel - var state NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 153, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jdbcDrivers", Field: "JdbcDrivers", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NifiResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NifiResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NifiResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/19_vc_org_reconcile_action.go b/generated/dev/go/19_vc_org_reconcile_action.go deleted file mode 100644 index a8fd701..0000000 --- a/generated/dev/go/19_vc_org_reconcile_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_org -// Action: reconcile - -var _ resource.Resource = &VcOrgReconcileResource{} - -// VcOrgReconcileResource triggers a one-time action. -type VcOrgReconcileResource struct { - client *core.UniversalClient -} - -type VcOrgReconcileModel struct { - ID types.String `tfsdk:"id"` - VcOrgID types.String `tfsdk:"vc_org_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewVcOrgReconcileResource() resource.Resource { - return &VcOrgReconcileResource{} -} - -func (r *VcOrgReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_org_reconcile" -} - -func (r *VcOrgReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_org_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcOrgReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcOrgReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcOrgID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcOrgReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcOrgReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcOrgReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcOrgID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcOrgReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcOrgReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/19_vc_org_resource.go b/generated/dev/go/19_vc_org_resource.go deleted file mode 100644 index d004f8c..0000000 --- a/generated/dev/go/19_vc_org_resource.go +++ /dev/null @@ -1,375 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_org -// Service ID: 19 - -var _ resource.Resource = &VcOrgResource{} -var _ resource.ResourceWithModifyPlan = &VcOrgResource{} -var _ resource.ResourceWithImportState = &VcOrgResource{} - -type VcOrgResource struct { - client *core.UniversalClient -} - -type VcOrgModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - OrganizationType types.String `tfsdk:"organization_type"` - ResourceRealm types.String `tfsdk:"resource_realm"` - VIPConfigure types.String `tfsdk:"v_i_p_configure"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcOrgResource() resource.Resource { - return &VcOrgResource{} -} - -func (r *VcOrgResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_org" -} - -func (r *VcOrgResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "organization_type": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("iaas"), MarkdownDescription: "Доступ к организации предоставляется только при выборе `iaas` Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Облако в котором будет развёрнут тенант Не изменяется после создания."}, - "v_i_p_configure": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]")}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcOrgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcOrgModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.OrganizationType.IsNull() && !plan.OrganizationType.IsUnknown() && !state.OrganizationType.IsNull() && !state.OrganizationType.IsUnknown() { - if plan.OrganizationType.ValueString() != state.OrganizationType.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить organization_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 418: resources_core.FormatString(config.ResourceRealm), - 556: resources_core.FormatString(config.OrganizationType), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 19, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcOrgResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 19, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 418: resources_core.FormatString(data.ResourceRealm), - 556: resources_core.FormatString(data.OrganizationType), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 19, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 19, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 19, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcOrgResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcOrgModel - var state VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.VIPConfigure.IsNull() != state.VIPConfigure.IsNull() || plan.VIPConfigure.IsUnknown() != state.VIPConfigure.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VIPConfigure.IsNull() && !plan.VIPConfigure.IsUnknown() && !state.VIPConfigure.IsNull() && !state.VIPConfigure.IsUnknown() { - if plan.VIPConfigure.ValueString() != state.VIPConfigure.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 662: resources_core.FormatString(plan.VIPConfigure), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 19, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcOrgResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcOrgResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/1_dummy_reconcile_action.go b/generated/dev/go/1_dummy_reconcile_action.go deleted file mode 100644 index e373bc2..0000000 --- a/generated/dev/go/1_dummy_reconcile_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dummy -// Action: reconcile - -var _ resource.Resource = &DummyReconcileResource{} - -// DummyReconcileResource triggers a one-time action. -type DummyReconcileResource struct { - client *core.UniversalClient -} - -type DummyReconcileModel struct { - ID types.String `tfsdk:"id"` - DummyID types.String `tfsdk:"dummy_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewDummyReconcileResource() resource.Resource { - return &DummyReconcileResource{} -} - -func (r *DummyReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dummy_reconcile" -} - -func (r *DummyReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "dummy_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DummyReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan DummyReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.DummyID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *DummyReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DummyReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DummyReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.DummyID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *DummyReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *DummyReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/1_dummy_redeploy_action.go b/generated/dev/go/1_dummy_redeploy_action.go deleted file mode 100644 index 60df6bb..0000000 --- a/generated/dev/go/1_dummy_redeploy_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dummy -// Action: redeploy - -var _ resource.Resource = &DummyRedeployResource{} - -// DummyRedeployResource triggers a one-time action. -type DummyRedeployResource struct { - client *core.UniversalClient -} - -type DummyRedeployModel struct { - ID types.String `tfsdk:"id"` - DummyID types.String `tfsdk:"dummy_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewDummyRedeployResource() resource.Resource { - return &DummyRedeployResource{} -} - -func (r *DummyRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dummy_redeploy" -} - -func (r *DummyRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "dummy_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DummyRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan DummyRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.DummyID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *DummyRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DummyRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DummyRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.DummyID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *DummyRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *DummyRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/1_dummy_resource.go b/generated/dev/go/1_dummy_resource.go deleted file mode 100644 index bb2e7ac..0000000 --- a/generated/dev/go/1_dummy_resource.go +++ /dev/null @@ -1,519 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dummy -// Service ID: 1 - -var _ resource.Resource = &DummyResource{} -var _ resource.ResourceWithModifyPlan = &DummyResource{} -var _ resource.ResourceWithImportState = &DummyResource{} - -type DummyResource struct { - client *core.UniversalClient -} - -type DummyModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ArrayMapFixedExample types.String `tfsdk:"array_map_fixed_example"` - Bodymessage types.String `tfsdk:"bodymessage"` - DurationMs types.Int64 `tfsdk:"duration_ms"` - FailAtStart types.Bool `tfsdk:"fail_at_start"` - FailInProgress types.Bool `tfsdk:"fail_in_progress"` - JsonExample types.String `tfsdk:"json_example"` - MapExample types.String `tfsdk:"map_example"` - MapFixed types.String `tfsdk:"map_fixed"` - NestedRefExample types.String `tfsdk:"nested_ref_example"` - ResourceRealm types.String `tfsdk:"resource_realm"` - WhereFail types.Int64 `tfsdk:"where_fail"` - YamlExample types.String `tfsdk:"yaml_example"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDummyResource() resource.Resource { - return &DummyResource{} -} - -func (r *DummyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dummy" -} - -func (r *DummyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "array_map_fixed_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Array of map-fixed Не изменяется после создания."}, - "bodymessage": schema.StringAttribute{Optional: true, MarkdownDescription: "Дата, уходящая в Vault"}, - "duration_ms": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "перед завершением подождать (sleep) столько миллисекунд"}, - "fail_at_start": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "если true, завершить джоб, ничего не записывая в cmdb"}, - "fail_in_progress": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb"}, - "json_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Для тестирования интерфейса", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "map_example": schema.StringAttribute{Optional: true}, - "map_fixed": schema.StringAttribute{Optional: true, MarkdownDescription: "Новый тип поля Не изменяется после создания."}, - "nested_ref_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "where_fail": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write"}, - "yaml_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DummyResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DummyModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ArrayMapFixedExample.IsNull() && !plan.ArrayMapFixedExample.IsUnknown() && !state.ArrayMapFixedExample.IsNull() && !state.ArrayMapFixedExample.IsUnknown() { - if plan.ArrayMapFixedExample.ValueString() != state.ArrayMapFixedExample.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить array_map_fixed_example", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MapFixed.IsNull() && !plan.MapFixed.IsUnknown() && !state.MapFixed.IsNull() && !state.MapFixed.IsUnknown() { - if plan.MapFixed.ValueString() != state.MapFixed.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить map_fixed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NestedRefExample.IsNull() && !plan.NestedRefExample.IsUnknown() && !state.NestedRefExample.IsNull() && !state.NestedRefExample.IsUnknown() { - if plan.NestedRefExample.ValueString() != state.NestedRefExample.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить nested_ref_example", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.YamlExample.IsNull() && !plan.YamlExample.IsUnknown() && !state.YamlExample.IsNull() && !state.YamlExample.IsUnknown() { - if plan.YamlExample.ValueString() != state.YamlExample.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить yaml_example", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 198: resources_core.FormatInt64(config.DurationMs), - 199: resources_core.FormatBool(config.FailAtStart), - 200: resources_core.FormatBool(config.FailInProgress), - 201: resources_core.FormatInt64(config.WhereFail), - 242: resources_core.FormatString(config.ResourceRealm), - 286: resources_core.FormatString(config.Bodymessage), - 321: resources_core.FormatString(config.MapExample), - 322: resources_core.FormatString(config.JsonExample), - 396: resources_core.FormatString(config.NestedRefExample), - 447: resources_core.FormatString(config.YamlExample), - 647: resources_core.FormatString(config.MapFixed), - 654: resources_core.FormatString(config.ArrayMapFixedExample), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 1, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DummyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 1, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 198: resources_core.FormatInt64(data.DurationMs), - 199: resources_core.FormatBool(data.FailAtStart), - 200: resources_core.FormatBool(data.FailInProgress), - 201: resources_core.FormatInt64(data.WhereFail), - 242: resources_core.FormatString(data.ResourceRealm), - 286: resources_core.FormatString(data.Bodymessage), - 321: resources_core.FormatString(data.MapExample), - 322: resources_core.FormatString(data.JsonExample), - 396: resources_core.FormatString(data.NestedRefExample), - 447: resources_core.FormatString(data.YamlExample), - 647: resources_core.FormatString(data.MapFixed), - 654: resources_core.FormatString(data.ArrayMapFixedExample), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 1, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 1, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - {Code: "yamlExample", Field: "YamlExample", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 1, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - {Code: "yamlExample", Field: "YamlExample", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DummyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DummyModel - var state DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.DurationMs.IsNull() != state.DurationMs.IsNull() || plan.DurationMs.IsUnknown() != state.DurationMs.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.DurationMs.IsNull() && !plan.DurationMs.IsUnknown() && !state.DurationMs.IsNull() && !state.DurationMs.IsUnknown() { - if plan.DurationMs.ValueInt64() != state.DurationMs.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.FailAtStart.IsNull() != state.FailAtStart.IsNull() || plan.FailAtStart.IsUnknown() != state.FailAtStart.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.FailAtStart.IsNull() && !plan.FailAtStart.IsUnknown() && !state.FailAtStart.IsNull() && !state.FailAtStart.IsUnknown() { - if plan.FailAtStart.ValueBool() != state.FailAtStart.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.FailInProgress.IsNull() != state.FailInProgress.IsNull() || plan.FailInProgress.IsUnknown() != state.FailInProgress.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.FailInProgress.IsNull() && !plan.FailInProgress.IsUnknown() && !state.FailInProgress.IsNull() && !state.FailInProgress.IsUnknown() { - if plan.FailInProgress.ValueBool() != state.FailInProgress.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.WhereFail.IsNull() != state.WhereFail.IsNull() || plan.WhereFail.IsUnknown() != state.WhereFail.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.WhereFail.IsNull() && !plan.WhereFail.IsUnknown() && !state.WhereFail.IsNull() && !state.WhereFail.IsUnknown() { - if plan.WhereFail.ValueInt64() != state.WhereFail.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.Bodymessage.IsNull() != state.Bodymessage.IsNull() || plan.Bodymessage.IsUnknown() != state.Bodymessage.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.Bodymessage.IsNull() && !plan.Bodymessage.IsUnknown() && !state.Bodymessage.IsNull() && !state.Bodymessage.IsUnknown() { - if plan.Bodymessage.ValueString() != state.Bodymessage.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MapExample.IsNull() != state.MapExample.IsNull() || plan.MapExample.IsUnknown() != state.MapExample.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MapExample.IsNull() && !plan.MapExample.IsUnknown() && !state.MapExample.IsNull() && !state.MapExample.IsUnknown() { - if plan.MapExample.ValueString() != state.MapExample.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonExample.IsNull() != state.JsonExample.IsNull() || plan.JsonExample.IsUnknown() != state.JsonExample.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonExample.IsNull() && !plan.JsonExample.IsUnknown() && !state.JsonExample.IsNull() && !state.JsonExample.IsUnknown() { - if plan.JsonExample.ValueString() != state.JsonExample.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 287: resources_core.FormatInt64(plan.DurationMs), - 288: resources_core.FormatBool(plan.FailAtStart), - 289: resources_core.FormatBool(plan.FailInProgress), - 290: resources_core.FormatInt64(plan.WhereFail), - 291: resources_core.FormatString(plan.Bodymessage), - 373: resources_core.FormatString(plan.MapExample), - 374: resources_core.FormatString(plan.JsonExample), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 1, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - {Code: "yamlExample", Field: "YamlExample", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DummyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DummyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/21_vc_vdc_reconcile_action.go b/generated/dev/go/21_vc_vdc_reconcile_action.go deleted file mode 100644 index 29801da..0000000 --- a/generated/dev/go/21_vc_vdc_reconcile_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc -// Action: reconcile - -var _ resource.Resource = &VcVdcReconcileResource{} - -// VcVdcReconcileResource triggers a one-time action. -type VcVdcReconcileResource struct { - client *core.UniversalClient -} - -type VcVdcReconcileModel struct { - ID types.String `tfsdk:"id"` - VcVdcID types.String `tfsdk:"vc_vdc_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewVcVdcReconcileResource() resource.Resource { - return &VcVdcReconcileResource{} -} - -func (r *VcVdcReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_reconcile" -} - -func (r *VcVdcReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vdc_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVdcReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/21_vc_vdc_resource.go b/generated/dev/go/21_vc_vdc_resource.go deleted file mode 100644 index d3aff33..0000000 --- a/generated/dev/go/21_vc_vdc_resource.go +++ /dev/null @@ -1,512 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc -// Service ID: 21 - -var _ resource.Resource = &VcVdcResource{} -var _ resource.ResourceWithModifyPlan = &VcVdcResource{} -var _ resource.ResourceWithImportState = &VcVdcResource{} - -type VcVdcResource struct { - client *core.UniversalClient -} - -type VcVdcModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - CpuAllocated types.Int64 `tfsdk:"cpu_allocated"` - CpuGuaranteed types.Int64 `tfsdk:"cpu_guaranteed"` - MemAllocated types.Int64 `tfsdk:"mem_allocated"` - NetworkProvider types.String `tfsdk:"network_provider"` - OrganizationUid types.String `tfsdk:"organization_uid"` - ProviderVdc types.String `tfsdk:"provider_vdc"` - StorageConfig types.String `tfsdk:"storage_config"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVdcResource() resource.Resource { - return &VcVdcResource{} -} - -func (r *VcVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc" -} - -func (r *VcVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "cpu_allocated": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "шт"}, - "cpu_guaranteed": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "% резервирования Не изменяется после создания."}, - "mem_allocated": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "gb"}, - "network_provider": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "organization_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` Не изменяется после создания."}, - "provider_vdc": schema.StringAttribute{Required: true, MarkdownDescription: "Приписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
Не изменяется после создания."}, - "storage_config": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Первая политика в списке указывается как "По умолчанию""}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVdcModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.OrganizationUid.IsNull() && !plan.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, plan.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != plan.OrganizationUid.ValueString() { - plan.OrganizationUid = types.StringValue(resolvedOrganizationUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.CpuGuaranteed.IsNull() && !plan.CpuGuaranteed.IsUnknown() && !state.CpuGuaranteed.IsNull() && !state.CpuGuaranteed.IsUnknown() { - if plan.CpuGuaranteed.ValueInt64() != state.CpuGuaranteed.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить cpu_guaranteed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NetworkProvider.IsNull() && !plan.NetworkProvider.IsUnknown() && !state.NetworkProvider.IsNull() && !state.NetworkProvider.IsUnknown() { - if plan.NetworkProvider.ValueString() != state.NetworkProvider.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить network_provider", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.OrganizationUid.IsNull() && !plan.OrganizationUid.IsUnknown() && !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - if plan.OrganizationUid.ValueString() != state.OrganizationUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить organization_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ProviderVdc.IsNull() && !plan.ProviderVdc.IsUnknown() && !state.ProviderVdc.IsNull() && !state.ProviderVdc.IsUnknown() { - if plan.ProviderVdc.ValueString() != state.ProviderVdc.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить provider_vdc", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.NetworkProvider.IsNull() || config.NetworkProvider.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "network_provider is required.") - return - } - if config.OrganizationUid.IsNull() || config.OrganizationUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "organization_uid is required.") - return - } - if config.ProviderVdc.IsNull() || config.ProviderVdc.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "provider_vdc is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.OrganizationUid.IsNull() && !config.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, config.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != config.OrganizationUid.ValueString() { - config.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - params := map[int]string{ - 30: resources_core.FormatString(config.OrganizationUid), - 335: resources_core.FormatString(config.ProviderVdc), - 361: resources_core.FormatString(config.StorageConfig), - 397: resources_core.FormatInt64(config.CpuGuaranteed), - 557: resources_core.FormatInt64(config.CpuAllocated), - 558: resources_core.FormatInt64(config.MemAllocated), - 746: resources_core.FormatString(config.NetworkProvider), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 21, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.NetworkProvider.IsNull() || data.NetworkProvider.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "network_provider is required.") - return - } - if data.OrganizationUid.IsNull() || data.OrganizationUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "organization_uid is required.") - return - } - if data.ProviderVdc.IsNull() || data.ProviderVdc.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "provider_vdc is required.") - return - } - if !data.OrganizationUid.IsNull() && !data.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, data.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedOrganizationUid != "" && resolvedOrganizationUid != data.OrganizationUid.ValueString() { - data.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 21, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 30: resources_core.FormatString(data.OrganizationUid), - 335: resources_core.FormatString(data.ProviderVdc), - 361: resources_core.FormatString(data.StorageConfig), - 397: resources_core.FormatInt64(data.CpuGuaranteed), - 557: resources_core.FormatInt64(data.CpuAllocated), - 558: resources_core.FormatInt64(data.MemAllocated), - 746: resources_core.FormatString(data.NetworkProvider), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 21, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 21, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, state.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != state.OrganizationUid.ValueString() { - state.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 21, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.OrganizationUid.IsNull() && !newState.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, newState.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != newState.OrganizationUid.ValueString() { - newState.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcModel - var state VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.CpuAllocated.IsNull() != state.CpuAllocated.IsNull() || plan.CpuAllocated.IsUnknown() != state.CpuAllocated.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.CpuAllocated.IsNull() && !plan.CpuAllocated.IsUnknown() && !state.CpuAllocated.IsNull() && !state.CpuAllocated.IsUnknown() { - if plan.CpuAllocated.ValueInt64() != state.CpuAllocated.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MemAllocated.IsNull() != state.MemAllocated.IsNull() || plan.MemAllocated.IsUnknown() != state.MemAllocated.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MemAllocated.IsNull() && !plan.MemAllocated.IsUnknown() && !state.MemAllocated.IsNull() && !state.MemAllocated.IsUnknown() { - if plan.MemAllocated.ValueInt64() != state.MemAllocated.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.StorageConfig.IsNull() != state.StorageConfig.IsNull() || plan.StorageConfig.IsUnknown() != state.StorageConfig.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.StorageConfig.IsNull() && !plan.StorageConfig.IsUnknown() && !state.StorageConfig.IsNull() && !state.StorageConfig.IsUnknown() { - if plan.StorageConfig.ValueString() != state.StorageConfig.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 560: resources_core.FormatInt64(plan.CpuAllocated), - 561: resources_core.FormatInt64(plan.MemAllocated), - 562: resources_core.FormatString(plan.StorageConfig), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 21, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, state.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != state.OrganizationUid.ValueString() { - state.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVdcResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVdcResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/22_vc_nsxt_reconcile_action.go b/generated/dev/go/22_vc_nsxt_reconcile_action.go deleted file mode 100644 index d04cbfa..0000000 --- a/generated/dev/go/22_vc_nsxt_reconcile_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_nsxt -// Action: reconcile - -var _ resource.Resource = &VcNsxtReconcileResource{} - -// VcNsxtReconcileResource triggers a one-time action. -type VcNsxtReconcileResource struct { - client *core.UniversalClient -} - -type VcNsxtReconcileModel struct { - ID types.String `tfsdk:"id"` - VcNsxtID types.String `tfsdk:"vc_nsxt_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewVcNsxtReconcileResource() resource.Resource { - return &VcNsxtReconcileResource{} -} - -func (r *VcNsxtReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_nsxt_reconcile" -} - -func (r *VcNsxtReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_nsxt_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcNsxtReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcNsxtReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcNsxtID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcNsxtReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcNsxtReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcNsxtReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcNsxtReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcNsxtID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcNsxtReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcNsxtReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/22_vc_nsxt_resource.go b/generated/dev/go/22_vc_nsxt_resource.go deleted file mode 100644 index 1e4add5..0000000 --- a/generated/dev/go/22_vc_nsxt_resource.go +++ /dev/null @@ -1,536 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_nsxt -// Service ID: 22 - -var _ resource.Resource = &VcNsxtResource{} -var _ resource.ResourceWithModifyPlan = &VcNsxtResource{} -var _ resource.ResourceWithImportState = &VcNsxtResource{} - -type VcNsxtResource struct { - client *core.UniversalClient -} - -type VcNsxtModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - NeedEnableAVI types.Bool `tfsdk:"need_enable_a_v_i"` - NeedExternalAddressSNAT types.Bool `tfsdk:"need_external_address_s_n_a_t"` - VdcGroupUid types.String `tfsdk:"vdc_group_uid"` - VdcType types.String `tfsdk:"vdc_type"` - VdcUid types.String `tfsdk:"vdc_uid"` - VirtualServicesCount types.Int64 `tfsdk:"virtual_services_count"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcNsxtResource() resource.Resource { - return &VcNsxtResource{} -} - -func (r *VcNsxtResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_nsxt" -} - -func (r *VcNsxtResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ip Space для внешнего IP"}, - "need_enable_a_v_i": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включение Load Balancer"}, - "need_external_address_s_n_a_t": schema.BoolAttribute{Optional: true, MarkdownDescription: "Создать правило SNAT на подсеть `10.10.102.0/24`"}, - "vdc_group_uid": schema.StringAttribute{Optional: true, MarkdownDescription: "UUID Услуги `Группа виртуальных датацентров (groupvDC)` Не изменяется после создания."}, - "vdc_type": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("vdc"), MarkdownDescription: "Тип родительской услуги Не изменяется после создания."}, - "vdc_uid": schema.StringAttribute{Optional: true, MarkdownDescription: "UUID Услуги `Виртуальный датацентр (vDC)` Не изменяется после создания."}, - "virtual_services_count": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Кол-во виртуальных сервисов, которые **резервируются** на AVI"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcNsxtResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcNsxtModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.VdcGroupUid.IsNull() && !plan.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, plan.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != plan.VdcGroupUid.ValueString() { - plan.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - planChanged = true - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() { - plan.VdcUid = types.StringValue(resolvedVdcUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.VdcGroupUid.IsNull() && !plan.VdcGroupUid.IsUnknown() && !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - if plan.VdcGroupUid.ValueString() != state.VdcGroupUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_group_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcType.IsNull() && !plan.VdcType.IsUnknown() && !state.VdcType.IsNull() && !state.VdcType.IsUnknown() { - if plan.VdcType.ValueString() != state.VdcType.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if plan.VdcUid.ValueString() != state.VdcUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VdcGroupUid.IsNull() && !config.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, config.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != config.VdcGroupUid.ValueString() { - config.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 8: resources_core.FormatString(config.VdcUid), - 340: resources_core.FormatBool(config.NeedEnableAVI), - 341: resources_core.FormatInt64(config.VirtualServicesCount), - 621: resources_core.FormatString(config.VdcType), - 622: resources_core.FormatString(config.VdcGroupUid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 22, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcNsxtResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if !data.VdcGroupUid.IsNull() && !data.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, data.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != data.VdcGroupUid.ValueString() { - data.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 22, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 8: resources_core.FormatString(data.VdcUid), - 340: resources_core.FormatBool(data.NeedEnableAVI), - 341: resources_core.FormatInt64(data.VirtualServicesCount), - 621: resources_core.FormatString(data.VdcType), - 622: resources_core.FormatString(data.VdcGroupUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 22, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 22, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, state.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != state.VdcGroupUid.ValueString() { - state.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcNsxtResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 22, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VdcGroupUid.IsNull() && !newState.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, newState.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != newState.VdcGroupUid.ValueString() { - newState.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcNsxtResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcNsxtModel - var state VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.NeedEnableAVI.IsNull() != state.NeedEnableAVI.IsNull() || plan.NeedEnableAVI.IsUnknown() != state.NeedEnableAVI.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedEnableAVI.IsNull() && !plan.NeedEnableAVI.IsUnknown() && !state.NeedEnableAVI.IsNull() && !state.NeedEnableAVI.IsUnknown() { - if plan.NeedEnableAVI.ValueBool() != state.NeedEnableAVI.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VirtualServicesCount.IsNull() != state.VirtualServicesCount.IsNull() || plan.VirtualServicesCount.IsUnknown() != state.VirtualServicesCount.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VirtualServicesCount.IsNull() && !plan.VirtualServicesCount.IsUnknown() && !state.VirtualServicesCount.IsNull() && !state.VirtualServicesCount.IsUnknown() { - if plan.VirtualServicesCount.ValueInt64() != state.VirtualServicesCount.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressSNAT.IsNull() != state.NeedExternalAddressSNAT.IsNull() || plan.NeedExternalAddressSNAT.IsUnknown() != state.NeedExternalAddressSNAT.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressSNAT.IsNull() && !plan.NeedExternalAddressSNAT.IsUnknown() && !state.NeedExternalAddressSNAT.IsNull() && !state.NeedExternalAddressSNAT.IsUnknown() { - if plan.NeedExternalAddressSNAT.ValueBool() != state.NeedExternalAddressSNAT.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 368: resources_core.FormatBool(plan.NeedEnableAVI), - 369: resources_core.FormatInt64(plan.VirtualServicesCount), - 371: resources_core.FormatBool(plan.NeedExternalAddressSNAT), - 372: resources_core.FormatString(plan.IpSpaceName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 22, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, state.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != state.VdcGroupUid.ValueString() { - state.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcNsxtResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcNsxtResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcNsxtResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/25_vcexternalip_resource.go b/generated/dev/go/25_vcexternalip_resource.go deleted file mode 100644 index d068b24..0000000 --- a/generated/dev/go/25_vcexternalip_resource.go +++ /dev/null @@ -1,569 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vcexternalip -// Service ID: 25 - -var _ resource.Resource = &VcexternalipResource{} -var _ resource.ResourceWithModifyPlan = &VcexternalipResource{} -var _ resource.ResourceWithImportState = &VcexternalipResource{} - -type VcexternalipResource struct { - client *core.UniversalClient -} - -type VcexternalipModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DnatCreate types.Bool `tfsdk:"dnat_create"` - FromServiceCloudEdgeName types.String `tfsdk:"from_service_cloud_edge_name"` - FromServiceCloudEdgeScope types.String `tfsdk:"from_service_cloud_edge_scope"` - FromServiceCloudOrgName types.String `tfsdk:"from_service_cloud_org_name"` - FromServiceCloudVdcName types.String `tfsdk:"from_service_cloud_vdc_name"` - FromServiceCloudVmwareUrl types.String `tfsdk:"from_service_cloud_vmware_url"` - FromServiceNamespace types.String `tfsdk:"from_service_namespace"` - FromServiceVdcGroupName types.String `tfsdk:"from_service_vdc_group_name"` - InternalAddrAccess types.String `tfsdk:"internal_addr_access"` - InternalPortAccess types.String `tfsdk:"internal_port_access"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - ResourceRealm types.String `tfsdk:"resource_realm"` - ServiceUid types.String `tfsdk:"service_uid"` - SnatCreate types.Bool `tfsdk:"snat_create"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcexternalipResource() resource.Resource { - return &VcexternalipResource{} -} - -func (r *VcexternalipResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vcexternalip" -} - -func (r *VcexternalipResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "dnat_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Необходимо создать DNAT-правило."}, - "from_service_cloud_edge_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Edge составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_edge_scope": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "from_service_cloud_org_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Org составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_vdc_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Vdc составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_vmware_url": schema.StringAttribute{Optional: true, MarkdownDescription: "Api-Url составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_namespace": schema.StringAttribute{Required: true, MarkdownDescription: "Namespace составной услуги (для отображения правил FW) Не изменяется после создания."}, - "from_service_vdc_group_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "internal_addr_access": schema.StringAttribute{Required: true, MarkdownDescription: "Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true"}, - "internal_port_access": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("5432"), MarkdownDescription: "Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
"}, - "ip_space_name": schema.StringAttribute{Required: true, MarkdownDescription: "Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "service_uid": schema.StringAttribute{Required: true}, - "snat_create": schema.BoolAttribute{Optional: true, MarkdownDescription: "Необходимо создать SNAT-правило.
"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcexternalipResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcexternalipModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.FromServiceCloudEdgeName.IsNull() && !plan.FromServiceCloudEdgeName.IsUnknown() && !state.FromServiceCloudEdgeName.IsNull() && !state.FromServiceCloudEdgeName.IsUnknown() { - if plan.FromServiceCloudEdgeName.ValueString() != state.FromServiceCloudEdgeName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_edge_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudEdgeScope.IsNull() && !plan.FromServiceCloudEdgeScope.IsUnknown() && !state.FromServiceCloudEdgeScope.IsNull() && !state.FromServiceCloudEdgeScope.IsUnknown() { - if plan.FromServiceCloudEdgeScope.ValueString() != state.FromServiceCloudEdgeScope.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_edge_scope", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudOrgName.IsNull() && !plan.FromServiceCloudOrgName.IsUnknown() && !state.FromServiceCloudOrgName.IsNull() && !state.FromServiceCloudOrgName.IsUnknown() { - if plan.FromServiceCloudOrgName.ValueString() != state.FromServiceCloudOrgName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_org_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudVdcName.IsNull() && !plan.FromServiceCloudVdcName.IsUnknown() && !state.FromServiceCloudVdcName.IsNull() && !state.FromServiceCloudVdcName.IsUnknown() { - if plan.FromServiceCloudVdcName.ValueString() != state.FromServiceCloudVdcName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_vdc_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudVmwareUrl.IsNull() && !plan.FromServiceCloudVmwareUrl.IsUnknown() && !state.FromServiceCloudVmwareUrl.IsNull() && !state.FromServiceCloudVmwareUrl.IsUnknown() { - if plan.FromServiceCloudVmwareUrl.ValueString() != state.FromServiceCloudVmwareUrl.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_vmware_url", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceNamespace.IsNull() && !plan.FromServiceNamespace.IsUnknown() && !state.FromServiceNamespace.IsNull() && !state.FromServiceNamespace.IsUnknown() { - if plan.FromServiceNamespace.ValueString() != state.FromServiceNamespace.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_namespace", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceVdcGroupName.IsNull() && !plan.FromServiceVdcGroupName.IsUnknown() && !state.FromServiceVdcGroupName.IsNull() && !state.FromServiceVdcGroupName.IsUnknown() { - if plan.FromServiceVdcGroupName.ValueString() != state.FromServiceVdcGroupName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_vdc_group_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.FromServiceNamespace.IsNull() || config.FromServiceNamespace.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "from_service_namespace is required.") - return - } - if config.InternalAddrAccess.IsNull() || config.InternalAddrAccess.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "internal_addr_access is required.") - return - } - if config.IpSpaceName.IsNull() || config.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ServiceUid.IsNull() || config.ServiceUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "service_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 140: resources_core.FormatString(config.ServiceUid), - 141: resources_core.FormatBool(config.DnatCreate), - 142: resources_core.FormatString(config.InternalPortAccess), - 143: resources_core.FormatBool(config.SnatCreate), - 144: resources_core.FormatString(config.InternalAddrAccess), - 324: resources_core.FormatString(config.FromServiceNamespace), - 325: resources_core.FormatString(config.FromServiceCloudEdgeName), - 326: resources_core.FormatString(config.FromServiceCloudVdcName), - 327: resources_core.FormatString(config.FromServiceCloudOrgName), - 328: resources_core.FormatString(config.FromServiceCloudVmwareUrl), - 336: resources_core.FormatString(config.IpSpaceName), - 488: resources_core.FormatString(config.ResourceRealm), - 624: resources_core.FormatString(config.FromServiceCloudEdgeScope), - 626: resources_core.FormatString(config.FromServiceVdcGroupName), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 25, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcexternalipResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.FromServiceNamespace.IsNull() || data.FromServiceNamespace.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "from_service_namespace is required.") - return - } - if data.InternalAddrAccess.IsNull() || data.InternalAddrAccess.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "internal_addr_access is required.") - return - } - if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.ServiceUid.IsNull() || data.ServiceUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "service_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 25, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 140: resources_core.FormatString(data.ServiceUid), - 141: resources_core.FormatBool(data.DnatCreate), - 142: resources_core.FormatString(data.InternalPortAccess), - 143: resources_core.FormatBool(data.SnatCreate), - 144: resources_core.FormatString(data.InternalAddrAccess), - 324: resources_core.FormatString(data.FromServiceNamespace), - 325: resources_core.FormatString(data.FromServiceCloudEdgeName), - 326: resources_core.FormatString(data.FromServiceCloudVdcName), - 327: resources_core.FormatString(data.FromServiceCloudOrgName), - 328: resources_core.FormatString(data.FromServiceCloudVmwareUrl), - 336: resources_core.FormatString(data.IpSpaceName), - 488: resources_core.FormatString(data.ResourceRealm), - 624: resources_core.FormatString(data.FromServiceCloudEdgeScope), - 626: resources_core.FormatString(data.FromServiceVdcGroupName), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 25, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 25, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcexternalipResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 25, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcexternalipResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcexternalipModel - var state VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ServiceUid.IsNull() != state.ServiceUid.IsNull() || plan.ServiceUid.IsUnknown() != state.ServiceUid.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ServiceUid.IsNull() && !plan.ServiceUid.IsUnknown() && !state.ServiceUid.IsNull() && !state.ServiceUid.IsUnknown() { - if plan.ServiceUid.ValueString() != state.ServiceUid.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.DnatCreate.IsNull() != state.DnatCreate.IsNull() || plan.DnatCreate.IsUnknown() != state.DnatCreate.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.DnatCreate.IsNull() && !plan.DnatCreate.IsUnknown() && !state.DnatCreate.IsNull() && !state.DnatCreate.IsUnknown() { - if plan.DnatCreate.ValueBool() != state.DnatCreate.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.SnatCreate.IsNull() != state.SnatCreate.IsNull() || plan.SnatCreate.IsUnknown() != state.SnatCreate.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.SnatCreate.IsNull() && !plan.SnatCreate.IsUnknown() && !state.SnatCreate.IsNull() && !state.SnatCreate.IsUnknown() { - if plan.SnatCreate.ValueBool() != state.SnatCreate.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.InternalPortAccess.IsNull() != state.InternalPortAccess.IsNull() || plan.InternalPortAccess.IsUnknown() != state.InternalPortAccess.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.InternalPortAccess.IsNull() && !plan.InternalPortAccess.IsUnknown() && !state.InternalPortAccess.IsNull() && !state.InternalPortAccess.IsUnknown() { - if plan.InternalPortAccess.ValueString() != state.InternalPortAccess.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.InternalAddrAccess.IsNull() != state.InternalAddrAccess.IsNull() || plan.InternalAddrAccess.IsUnknown() != state.InternalAddrAccess.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.InternalAddrAccess.IsNull() && !plan.InternalAddrAccess.IsUnknown() && !state.InternalAddrAccess.IsNull() && !state.InternalAddrAccess.IsUnknown() { - if plan.InternalAddrAccess.ValueString() != state.InternalAddrAccess.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 627: resources_core.FormatString(plan.ServiceUid), - 628: resources_core.FormatString(plan.IpSpaceName), - 629: resources_core.FormatBool(plan.DnatCreate), - 630: resources_core.FormatBool(plan.SnatCreate), - 631: resources_core.FormatString(plan.InternalPortAccess), - 632: resources_core.FormatString(plan.InternalAddrAccess), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 25, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcexternalipResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcexternalipResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcexternalipResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/26_vapp_resource.go b/generated/dev/go/26_vapp_resource.go deleted file mode 100644 index 2044004..0000000 --- a/generated/dev/go/26_vapp_resource.go +++ /dev/null @@ -1,496 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vapp -// Service ID: 26 - -var _ resource.Resource = &VappResource{} -var _ resource.ResourceWithModifyPlan = &VappResource{} -var _ resource.ResourceWithImportState = &VappResource{} - -type VappResource struct { - client *core.UniversalClient -} - -type VappModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - NsxtUid types.String `tfsdk:"nsxt_uid"` - VappName types.String `tfsdk:"vapp_name"` - VdcUid types.String `tfsdk:"vdc_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVappResource() resource.Resource { - return &VappResource{} -} - -func (r *VappResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vapp" -} - -func (r *VappResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "nsxt_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги `Сетевой шлюз периметра (Edge)` Не изменяется после создания."}, - "vapp_name": schema.StringAttribute{Required: true, MarkdownDescription: "Уникальное в рамках организации Не изменяется после создания."}, - "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги `Виртуальный датацентр (vDC)` Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VappResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VappModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, plan.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != plan.NsxtUid.ValueString() { - plan.NsxtUid = types.StringValue(resolvedNsxtUid) - planChanged = true - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() { - plan.VdcUid = types.StringValue(resolvedVdcUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - if plan.NsxtUid.ValueString() != state.NsxtUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить nsxt_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappName.IsNull() && !plan.VappName.IsUnknown() && !state.VappName.IsNull() && !state.VappName.IsUnknown() { - if plan.VappName.ValueString() != state.VappName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vapp_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if plan.VdcUid.ValueString() != state.VdcUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.NsxtUid.IsNull() || config.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if config.VappName.IsNull() || config.VappName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.NsxtUid.IsNull() && !config.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, config.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != config.NsxtUid.ValueString() { - config.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 190: resources_core.FormatString(config.NsxtUid), - 191: resources_core.FormatString(config.VappName), - 623: resources_core.FormatString(config.VdcUid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 26, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VappResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.NsxtUid.IsNull() || data.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if data.VappName.IsNull() || data.VappName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if !data.NsxtUid.IsNull() && !data.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, data.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedNsxtUid != "" && resolvedNsxtUid != data.NsxtUid.ValueString() { - data.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 26, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 190: resources_core.FormatString(data.NsxtUid), - 191: resources_core.FormatString(data.VappName), - 623: resources_core.FormatString(data.VdcUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 26, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 26, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VappResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 26, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.NsxtUid.IsNull() && !newState.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, newState.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != newState.NsxtUid.ValueString() { - newState.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VappResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VappModel - var state VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 26, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VappResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VappResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VappResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/28_vc_vm_v3_redeploy_action.go b/generated/dev/go/28_vc_vm_v3_redeploy_action.go deleted file mode 100644 index 7185491..0000000 --- a/generated/dev/go/28_vc_vm_v3_redeploy_action.go +++ /dev/null @@ -1,207 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm_v3 -// Action: redeploy - -var _ resource.Resource = &VcVmV3RedeployResource{} - -// VcVmV3RedeployResource triggers a one-time action. -type VcVmV3RedeployResource struct { - client *core.UniversalClient -} - -type VcVmV3RedeployModel struct { - ID types.String `tfsdk:"id"` - VcVmV3ID types.String `tfsdk:"vc_vm_v3_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - VmName types.String `tfsdk:"vm_name"` - VmCpu types.Int64 `tfsdk:"vm_cpu"` - VmRam types.Int64 `tfsdk:"vm_ram"` - VmDisk types.Int64 `tfsdk:"vm_disk"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - AccessIpList types.String `tfsdk:"access_ip_list"` - ImageVm types.String `tfsdk:"image_vm"` - UserLogin types.String `tfsdk:"user_login"` - UserPublicKey types.String `tfsdk:"user_public_key"` - CloudInit types.String `tfsdk:"cloud_init"` - AccessPortList types.String `tfsdk:"access_port_list"` -} - -func NewVcVmV3RedeployResource() resource.Resource { - return &VcVmV3RedeployResource{} -} - -func (r *VcVmV3RedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm_v3_redeploy" -} - -func (r *VcVmV3RedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vm_v3_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "vm_name": schema.StringAttribute{Required: true}, - "vm_cpu": schema.Int64Attribute{Required: true, MarkdownDescription: "шт"}, - "vm_ram": schema.Int64Attribute{Required: true, MarkdownDescription: "Gb"}, - "vm_disk": schema.Int64Attribute{Optional: true, MarkdownDescription: "Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму"}, - "ip_space_name": schema.StringAttribute{Optional: true, MarkdownDescription: "no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev"}, - "access_ip_list": schema.StringAttribute{Optional: true, MarkdownDescription: "Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"]", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "image_vm": schema.StringAttribute{Required: true}, - "user_login": schema.StringAttribute{Required: true, MarkdownDescription: "Учётка SSH"}, - "user_public_key": schema.StringAttribute{Required: true, MarkdownDescription: "Публичная часть SSH-Ключа для пользователя"}, - "cloud_init": schema.StringAttribute{Optional: true, MarkdownDescription: "Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов."}, - "access_port_list": schema.StringAttribute{Optional: true, MarkdownDescription: "По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmV3RedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVmV3RedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.VmName.IsNull() || plan.VmName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vm_name is required.") - return - } - if plan.VmCpu.IsNull() || plan.VmCpu.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vm_cpu is required.") - return - } - if plan.VmRam.IsNull() || plan.VmRam.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vm_ram is required.") - return - } - if plan.ImageVm.IsNull() || plan.ImageVm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.") - return - } - if plan.UserLogin.IsNull() || plan.UserLogin.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_login is required.") - return - } - if plan.UserPublicKey.IsNull() || plan.UserPublicKey.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.") - return - } - - instanceUID := strings.TrimSpace(plan.VcVmV3ID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vmName": resources_core.FormatString(plan.VmName), - "vmCpu": resources_core.FormatInt64(plan.VmCpu), - "vmRam": resources_core.FormatInt64(plan.VmRam), - "vmDisk": resources_core.FormatInt64(plan.VmDisk), - "ipSpaceName": resources_core.FormatString(plan.IpSpaceName), - "accessIpList": resources_core.FormatString(plan.AccessIpList), - "imageVm": resources_core.FormatString(plan.ImageVm), - "userLogin": resources_core.FormatString(plan.UserLogin), - "userPublicKey": resources_core.FormatString(plan.UserPublicKey), - "cloudInit": resources_core.FormatString(plan.CloudInit), - "accessPortList": resources_core.FormatString(plan.AccessPortList), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVmV3RedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmV3RedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV3RedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmV3RedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVmV3ID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vmName": resources_core.FormatString(plan.VmName), - "vmCpu": resources_core.FormatInt64(plan.VmCpu), - "vmRam": resources_core.FormatInt64(plan.VmRam), - "vmDisk": resources_core.FormatInt64(plan.VmDisk), - "ipSpaceName": resources_core.FormatString(plan.IpSpaceName), - "accessIpList": resources_core.FormatString(plan.AccessIpList), - "imageVm": resources_core.FormatString(plan.ImageVm), - "userLogin": resources_core.FormatString(plan.UserLogin), - "userPublicKey": resources_core.FormatString(plan.UserPublicKey), - "cloudInit": resources_core.FormatString(plan.CloudInit), - "accessPortList": resources_core.FormatString(plan.AccessPortList), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVmV3RedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVmV3RedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/28_vc_vm_v3_resource.go b/generated/dev/go/28_vc_vm_v3_resource.go deleted file mode 100644 index 6673ac6..0000000 --- a/generated/dev/go/28_vc_vm_v3_resource.go +++ /dev/null @@ -1,598 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm_v3 -// Service ID: 28 - -var _ resource.Resource = &VcVmV3Resource{} -var _ resource.ResourceWithModifyPlan = &VcVmV3Resource{} -var _ resource.ResourceWithImportState = &VcVmV3Resource{} - -type VcVmV3Resource struct { - client *core.UniversalClient -} - -type VcVmV3Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessIpList types.String `tfsdk:"access_ip_list"` - AccessPortList types.String `tfsdk:"access_port_list"` - CloudInit types.String `tfsdk:"cloud_init"` - ImageVm types.String `tfsdk:"image_vm"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - UserLogin types.String `tfsdk:"user_login"` - UserPublicKey types.String `tfsdk:"user_public_key"` - VappUid types.String `tfsdk:"vapp_uid"` - VmCpu types.Int64 `tfsdk:"vm_cpu"` - VmDisk types.Int64 `tfsdk:"vm_disk"` - VmName types.String `tfsdk:"vm_name"` - VmRam types.Int64 `tfsdk:"vm_ram"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVmV3Resource() resource.Resource { - return &VcVmV3Resource{} -} - -func (r *VcVmV3Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm_v3" -} - -func (r *VcVmV3Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_ip_list": schema.StringAttribute{Optional: true, MarkdownDescription: "Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"]", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "access_port_list": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[\"22\"]"), MarkdownDescription: "По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX"}, - "cloud_init": schema.StringAttribute{Optional: true, MarkdownDescription: "Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. Не изменяется после создания."}, - "image_vm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "ip_space_name": schema.StringAttribute{Required: true}, - "user_login": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("myuser"), MarkdownDescription: "Учётка SSH Не изменяется после создания."}, - "user_public_key": schema.StringAttribute{Required: true, MarkdownDescription: "Публичная часть SSH-Ключа для пользователя Не изменяется после создания."}, - "vapp_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=26 (mapped to UUID in core) Не изменяется после создания."}, - "vm_cpu": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "шт"}, - "vm_disk": schema.Int64Attribute{Optional: true, MarkdownDescription: "Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму"}, - "vm_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Не изменяется после создания."}, - "vm_ram": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Gb"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmV3Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVmV3Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, plan.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != plan.VappUid.ValueString() { - plan.VappUid = types.StringValue(resolvedVappUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.CloudInit.IsNull() && !plan.CloudInit.IsUnknown() && !state.CloudInit.IsNull() && !state.CloudInit.IsUnknown() { - if plan.CloudInit.ValueString() != state.CloudInit.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить cloud_init", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ImageVm.IsNull() && !plan.ImageVm.IsUnknown() && !state.ImageVm.IsNull() && !state.ImageVm.IsUnknown() { - if plan.ImageVm.ValueString() != state.ImageVm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить image_vm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserLogin.IsNull() && !plan.UserLogin.IsUnknown() && !state.UserLogin.IsNull() && !state.UserLogin.IsUnknown() { - if plan.UserLogin.ValueString() != state.UserLogin.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить user_login", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserPublicKey.IsNull() && !plan.UserPublicKey.IsUnknown() && !state.UserPublicKey.IsNull() && !state.UserPublicKey.IsUnknown() { - if plan.UserPublicKey.ValueString() != state.UserPublicKey.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить user_public_key", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - if plan.VappUid.ValueString() != state.VappUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vapp_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VmName.IsNull() && !plan.VmName.IsUnknown() && !state.VmName.IsNull() && !state.VmName.IsUnknown() { - if plan.VmName.ValueString() != state.VmName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vm_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ImageVm.IsNull() || config.ImageVm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.") - return - } - if config.IpSpaceName.IsNull() || config.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if config.UserPublicKey.IsNull() || config.UserPublicKey.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.") - return - } - if config.VappUid.IsNull() || config.VappUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VappUid.IsNull() && !config.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, config.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != config.VappUid.ValueString() { - config.VappUid = types.StringValue(resolvedVappUid) - } - } - params := map[int]string{ - 407: resources_core.FormatString(config.VappUid), - 408: resources_core.FormatString(config.VmName), - 409: resources_core.FormatInt64(config.VmCpu), - 410: resources_core.FormatInt64(config.VmRam), - 411: resources_core.FormatInt64(config.VmDisk), - 412: resources_core.FormatString(config.IpSpaceName), - 413: resources_core.FormatString(config.AccessIpList), - 414: resources_core.FormatString(config.ImageVm), - 415: resources_core.FormatString(config.CloudInit), - 416: resources_core.FormatString(config.UserLogin), - 417: resources_core.FormatString(config.UserPublicKey), - 448: resources_core.FormatString(config.AccessPortList), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 28, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVmV3Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ImageVm.IsNull() || data.ImageVm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.") - return - } - if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if data.UserPublicKey.IsNull() || data.UserPublicKey.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.") - return - } - if data.VappUid.IsNull() || data.VappUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - if !data.VappUid.IsNull() && !data.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, data.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVappUid != "" && resolvedVappUid != data.VappUid.ValueString() { - data.VappUid = types.StringValue(resolvedVappUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 28, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 407: resources_core.FormatString(data.VappUid), - 408: resources_core.FormatString(data.VmName), - 409: resources_core.FormatInt64(data.VmCpu), - 410: resources_core.FormatInt64(data.VmRam), - 411: resources_core.FormatInt64(data.VmDisk), - 412: resources_core.FormatString(data.IpSpaceName), - 413: resources_core.FormatString(data.AccessIpList), - 414: resources_core.FormatString(data.ImageVm), - 415: resources_core.FormatString(data.CloudInit), - 416: resources_core.FormatString(data.UserLogin), - 417: resources_core.FormatString(data.UserPublicKey), - 448: resources_core.FormatString(data.AccessPortList), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 28, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 28, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV3Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 28, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VappUid.IsNull() && !newState.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, newState.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != newState.VappUid.ValueString() { - newState.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVmV3Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmV3Model - var state VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.VmCpu.IsNull() != state.VmCpu.IsNull() || plan.VmCpu.IsUnknown() != state.VmCpu.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmCpu.IsNull() && !plan.VmCpu.IsUnknown() && !state.VmCpu.IsNull() && !state.VmCpu.IsUnknown() { - if plan.VmCpu.ValueInt64() != state.VmCpu.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmRam.IsNull() != state.VmRam.IsNull() || plan.VmRam.IsUnknown() != state.VmRam.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmRam.IsNull() && !plan.VmRam.IsUnknown() && !state.VmRam.IsNull() && !state.VmRam.IsUnknown() { - if plan.VmRam.ValueInt64() != state.VmRam.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmDisk.IsNull() != state.VmDisk.IsNull() || plan.VmDisk.IsUnknown() != state.VmDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmDisk.IsNull() && !plan.VmDisk.IsUnknown() && !state.VmDisk.IsNull() && !state.VmDisk.IsUnknown() { - if plan.VmDisk.ValueInt64() != state.VmDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessIpList.IsNull() != state.AccessIpList.IsNull() || plan.AccessIpList.IsUnknown() != state.AccessIpList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessIpList.IsNull() && !plan.AccessIpList.IsUnknown() && !state.AccessIpList.IsNull() && !state.AccessIpList.IsUnknown() { - if plan.AccessIpList.ValueString() != state.AccessIpList.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessPortList.IsNull() != state.AccessPortList.IsNull() || plan.AccessPortList.IsUnknown() != state.AccessPortList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessPortList.IsNull() && !plan.AccessPortList.IsUnknown() && !state.AccessPortList.IsNull() && !state.AccessPortList.IsUnknown() { - if plan.AccessPortList.ValueString() != state.AccessPortList.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 493: resources_core.FormatInt64(plan.VmCpu), - 494: resources_core.FormatInt64(plan.VmRam), - 495: resources_core.FormatInt64(plan.VmDisk), - 496: resources_core.FormatString(plan.IpSpaceName), - 497: resources_core.FormatString(plan.AccessIpList), - 498: resources_core.FormatString(plan.AccessPortList), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 28, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV3Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVmV3Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVmV3Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/29_vc_vdc_group_add_vdc_action.go b/generated/dev/go/29_vc_vdc_group_add_vdc_action.go deleted file mode 100644 index 5b8b517..0000000 --- a/generated/dev/go/29_vc_vdc_group_add_vdc_action.go +++ /dev/null @@ -1,146 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Action: add_vdc - -var _ resource.Resource = &VcVdcGroupAddVdcResource{} - -// VcVdcGroupAddVdcResource triggers a one-time action. -type VcVdcGroupAddVdcResource struct { - client *core.UniversalClient -} - -type VcVdcGroupAddVdcModel struct { - ID types.String `tfsdk:"id"` - VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - VdcUid types.String `tfsdk:"vdc_uid"` -} - -func NewVcVdcGroupAddVdcResource() resource.Resource { - return &VcVdcGroupAddVdcResource{} -} - -func (r *VcVdcGroupAddVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_add_vdc" -} - -func (r *VcVdcGroupAddVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vdc_group_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=21 (mapped to UUID in core)"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupAddVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcGroupAddVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.VdcUid.IsNull() || plan.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vdcUid": resources_core.FormatString(plan.VdcUid), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "add_vdc", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "add_vdc", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupAddVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupAddVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupAddVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupAddVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vdcUid": resources_core.FormatString(plan.VdcUid), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "add_vdc", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "add_vdc", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupAddVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVdcGroupAddVdcResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/29_vc_vdc_group_reconcile_action.go b/generated/dev/go/29_vc_vdc_group_reconcile_action.go deleted file mode 100644 index e087664..0000000 --- a/generated/dev/go/29_vc_vdc_group_reconcile_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Action: reconcile - -var _ resource.Resource = &VcVdcGroupReconcileResource{} - -// VcVdcGroupReconcileResource triggers a one-time action. -type VcVdcGroupReconcileResource struct { - client *core.UniversalClient -} - -type VcVdcGroupReconcileModel struct { - ID types.String `tfsdk:"id"` - VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewVcVdcGroupReconcileResource() resource.Resource { - return &VcVdcGroupReconcileResource{} -} - -func (r *VcVdcGroupReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_reconcile" -} - -func (r *VcVdcGroupReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vdc_group_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcGroupReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVdcGroupReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/29_vc_vdc_group_remove_vdc_action.go b/generated/dev/go/29_vc_vdc_group_remove_vdc_action.go deleted file mode 100644 index 743d416..0000000 --- a/generated/dev/go/29_vc_vdc_group_remove_vdc_action.go +++ /dev/null @@ -1,146 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Action: remove_vdc - -var _ resource.Resource = &VcVdcGroupRemoveVdcResource{} - -// VcVdcGroupRemoveVdcResource triggers a one-time action. -type VcVdcGroupRemoveVdcResource struct { - client *core.UniversalClient -} - -type VcVdcGroupRemoveVdcModel struct { - ID types.String `tfsdk:"id"` - VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - VdcName types.String `tfsdk:"vdc_name"` -} - -func NewVcVdcGroupRemoveVdcResource() resource.Resource { - return &VcVdcGroupRemoveVdcResource{} -} - -func (r *VcVdcGroupRemoveVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_remove_vdc" -} - -func (r *VcVdcGroupRemoveVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vdc_group_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "vdc_name": schema.StringAttribute{Required: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupRemoveVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcGroupRemoveVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.VdcName.IsNull() || plan.VdcName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_name is required.") - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vdcName": resources_core.FormatString(plan.VdcName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "remove_vdc", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "remove_vdc", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupRemoveVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupRemoveVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupRemoveVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupRemoveVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vdcName": resources_core.FormatString(plan.VdcName), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "remove_vdc", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "remove_vdc", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupRemoveVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVdcGroupRemoveVdcResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/29_vc_vdc_group_resource.go b/generated/dev/go/29_vc_vdc_group_resource.go deleted file mode 100644 index 692769f..0000000 --- a/generated/dev/go/29_vc_vdc_group_resource.go +++ /dev/null @@ -1,400 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Service ID: 29 - -var _ resource.Resource = &VcVdcGroupResource{} -var _ resource.ResourceWithModifyPlan = &VcVdcGroupResource{} -var _ resource.ResourceWithImportState = &VcVdcGroupResource{} - -type VcVdcGroupResource struct { - client *core.UniversalClient -} - -type VcVdcGroupModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - VdcUid types.String `tfsdk:"vdc_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVdcGroupResource() resource.Resource { - return &VcVdcGroupResource{} -} - -func (r *VcVdcGroupResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group" -} - -func (r *VcVdcGroupResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=21 (mapped to UUID in core) Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVdcGroupModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() { - plan.VdcUid = types.StringValue(resolvedVdcUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if plan.VdcUid.ValueString() != state.VdcUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 618: resources_core.FormatString(config.VdcUid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 29, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVdcGroupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 29, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 618: resources_core.FormatString(data.VdcUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 29, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 29, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 29, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVdcGroupResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupModel - var state VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 29, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVdcGroupResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVdcGroupResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/2_template_resource.go b/generated/dev/go/2_template_resource.go deleted file mode 100644 index 01b8a84..0000000 --- a/generated/dev/go/2_template_resource.go +++ /dev/null @@ -1,435 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: template -// Service ID: 2 - -var _ resource.Resource = &TemplateResource{} -var _ resource.ResourceWithModifyPlan = &TemplateResource{} -var _ resource.ResourceWithImportState = &TemplateResource{} - -type TemplateResource struct { - client *core.UniversalClient -} - -type TemplateModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewTemplateResource() resource.Resource { - return &TemplateResource{} -} - -func (r *TemplateResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_template" -} - -func (r *TemplateResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100)}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200)}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *TemplateResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *TemplateModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 202: resources_core.FormatInt64(config.ResourceCPU), - 203: resources_core.FormatInt64(config.ResourceMemory), - 204: resources_core.FormatInt64(config.ResourceDisk), - 205: resources_core.FormatInt64(config.ResourceInstances), - 206: resources_core.FormatString(config.ResourceRealm), - 207: resources_core.FormatString(config.Domain), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 2, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *TemplateResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 2, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 202: resources_core.FormatInt64(data.ResourceCPU), - 203: resources_core.FormatInt64(data.ResourceMemory), - 204: resources_core.FormatInt64(data.ResourceDisk), - 205: resources_core.FormatInt64(data.ResourceInstances), - 206: resources_core.FormatString(data.ResourceRealm), - 207: resources_core.FormatString(data.Domain), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 2, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 2, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TemplateResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 2, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *TemplateResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan TemplateModel - var state TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 208: resources_core.FormatInt64(plan.ResourceCPU), - 209: resources_core.FormatInt64(plan.ResourceMemory), - 210: resources_core.FormatInt64(plan.ResourceDisk), - 211: resources_core.FormatInt64(plan.ResourceInstances), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 2, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TemplateResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *TemplateResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *TemplateResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/50_nextcloud_resource.go b/generated/dev/go/50_nextcloud_resource.go deleted file mode 100644 index 635d071..0000000 --- a/generated/dev/go/50_nextcloud_resource.go +++ /dev/null @@ -1,595 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nextcloud -// Service ID: 50 - -var _ resource.Resource = &NextcloudResource{} -var _ resource.ResourceWithModifyPlan = &NextcloudResource{} -var _ resource.ResourceWithImportState = &NextcloudResource{} - -type NextcloudResource struct { - client *core.UniversalClient -} - -type NextcloudModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AppVersion types.String `tfsdk:"app_version"` - DocumentServer types.String `tfsdk:"document_server"` - Domain types.String `tfsdk:"domain"` - PsqlUid types.String `tfsdk:"psql_uid"` - RedisUid types.String `tfsdk:"redis_uid"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNextcloudResource() resource.Resource { - return &NextcloudResource{} -} - -func (r *NextcloudResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nextcloud" -} - -func (r *NextcloudResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("32.0.1")}, - "document_server": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("collabora"), MarkdownDescription: "Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен
Размер пода collabora:
1.8 ядра. 2Gi ОЗУ Не изменяется после создания."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "psql_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=90 (mapped to UUID in core) Не изменяется после создания."}, - "redis_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=91 (mapped to UUID in core) Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(2), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)
Диск не может быть меньше 2G (!)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов
Не может пока быть больше одного, так как нужны SC под RWMany"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NextcloudResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NextcloudModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, plan.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != plan.PsqlUid.ValueString() { - plan.PsqlUid = types.StringValue(resolvedPsqlUid) - planChanged = true - } - } - if !plan.RedisUid.IsNull() && !plan.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, plan.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != plan.RedisUid.ValueString() { - plan.RedisUid = types.StringValue(resolvedRedisUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.DocumentServer.IsNull() && !plan.DocumentServer.IsUnknown() && !state.DocumentServer.IsNull() && !state.DocumentServer.IsUnknown() { - if plan.DocumentServer.ValueString() != state.DocumentServer.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить document_server", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - if plan.PsqlUid.ValueString() != state.PsqlUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить psql_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RedisUid.IsNull() && !plan.RedisUid.IsUnknown() && !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() { - if plan.RedisUid.ValueString() != state.RedisUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить redis_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.PsqlUid.IsNull() || config.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - if config.RedisUid.IsNull() || config.RedisUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "redis_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.PsqlUid.IsNull() && !config.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, config.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != config.PsqlUid.ValueString() { - config.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !config.RedisUid.IsNull() && !config.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, config.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != config.RedisUid.ValueString() { - config.RedisUid = types.StringValue(resolvedRedisUid) - } - } - params := map[int]string{ - 21: resources_core.FormatString(config.Domain), - 99: resources_core.FormatInt64(config.ResourceCPU), - 100: resources_core.FormatInt64(config.ResourceMemory), - 101: resources_core.FormatInt64(config.ResourceDisk), - 192: resources_core.FormatString(config.DocumentServer), - 470: resources_core.FormatInt64(config.ResourceInstances), - 564: resources_core.FormatString(config.PsqlUid), - 569: resources_core.FormatString(config.AppVersion), - 570: resources_core.FormatString(config.RedisUid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 50, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NextcloudResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.PsqlUid.IsNull() || data.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - if data.RedisUid.IsNull() || data.RedisUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "redis_uid is required.") - return - } - if !data.PsqlUid.IsNull() && !data.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, data.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedPsqlUid != "" && resolvedPsqlUid != data.PsqlUid.ValueString() { - data.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !data.RedisUid.IsNull() && !data.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, data.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedRedisUid != "" && resolvedRedisUid != data.RedisUid.ValueString() { - data.RedisUid = types.StringValue(resolvedRedisUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 50, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 21: resources_core.FormatString(data.Domain), - 99: resources_core.FormatInt64(data.ResourceCPU), - 100: resources_core.FormatInt64(data.ResourceMemory), - 101: resources_core.FormatInt64(data.ResourceDisk), - 192: resources_core.FormatString(data.DocumentServer), - 470: resources_core.FormatInt64(data.ResourceInstances), - 564: resources_core.FormatString(data.PsqlUid), - 569: resources_core.FormatString(data.AppVersion), - 570: resources_core.FormatString(data.RedisUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 50, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 50, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "documentServer", Field: "DocumentServer", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "redisUid", Field: "RedisUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, state.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != state.RedisUid.ValueString() { - state.RedisUid = types.StringValue(resolvedRedisUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 50, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "documentServer", Field: "DocumentServer", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "redisUid", Field: "RedisUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.PsqlUid.IsNull() && !newState.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, newState.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != newState.PsqlUid.ValueString() { - newState.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !newState.RedisUid.IsNull() && !newState.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, newState.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != newState.RedisUid.ValueString() { - newState.RedisUid = types.StringValue(resolvedRedisUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NextcloudResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NextcloudModel - var state NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 178: resources_core.FormatInt64(plan.ResourceCPU), - 179: resources_core.FormatInt64(plan.ResourceMemory), - 180: resources_core.FormatInt64(plan.ResourceDisk), - 547: resources_core.FormatInt64(plan.ResourceInstances), - 571: resources_core.FormatString(plan.AppVersion), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 50, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "documentServer", Field: "DocumentServer", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "redisUid", Field: "RedisUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, state.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != state.RedisUid.ValueString() { - state.RedisUid = types.StringValue(resolvedRedisUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NextcloudResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NextcloudResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/50_nextcloud_restart_action.go b/generated/dev/go/50_nextcloud_restart_action.go deleted file mode 100644 index d331a23..0000000 --- a/generated/dev/go/50_nextcloud_restart_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nextcloud -// Action: restart - -var _ resource.Resource = &NextcloudRestartResource{} - -// NextcloudRestartResource triggers a one-time action. -type NextcloudRestartResource struct { - client *core.UniversalClient -} - -type NextcloudRestartModel struct { - ID types.String `tfsdk:"id"` - NextcloudID types.String `tfsdk:"nextcloud_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewNextcloudRestartResource() resource.Resource { - return &NextcloudRestartResource{} -} - -func (r *NextcloudRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nextcloud_restart" -} - -func (r *NextcloudRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "nextcloud_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NextcloudRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan NextcloudRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.NextcloudID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NextcloudRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NextcloudRestartModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NextcloudRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.NextcloudID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NextcloudRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *NextcloudRestartResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/81_superset_resource.go b/generated/dev/go/81_superset_resource.go deleted file mode 100644 index e8c019c..0000000 --- a/generated/dev/go/81_superset_resource.go +++ /dev/null @@ -1,428 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: superset -// Service ID: 81 - -var _ resource.Resource = &SupersetResource{} -var _ resource.ResourceWithModifyPlan = &SupersetResource{} -var _ resource.ResourceWithImportState = &SupersetResource{} - -type SupersetResource struct { - client *core.UniversalClient -} - -type SupersetModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - Emails types.String `tfsdk:"emails"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewSupersetResource() resource.Resource { - return &SupersetResource{} -} - -func (r *SupersetResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_superset" -} - -func (r *SupersetResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "emails": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("testuser1"), MarkdownDescription: "Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *SupersetResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *SupersetModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Emails.IsNull() && !plan.Emails.IsUnknown() && !state.Emails.IsNull() && !state.Emails.IsUnknown() { - if plan.Emails.ValueString() != state.Emails.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить emails", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 14: resources_core.FormatString(config.Domain), - 20: resources_core.FormatString(config.Emails), - 96: resources_core.FormatInt64(config.ResourceCPU), - 97: resources_core.FormatInt64(config.ResourceMemory), - 98: resources_core.FormatInt64(config.ResourceDisk), - 109: resources_core.FormatString(config.ResourceRealm), - 227: resources_core.FormatInt64(config.ResourceInstances), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 81, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *SupersetResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 81, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 14: resources_core.FormatString(data.Domain), - 20: resources_core.FormatString(data.Emails), - 96: resources_core.FormatInt64(data.ResourceCPU), - 97: resources_core.FormatInt64(data.ResourceMemory), - 98: resources_core.FormatInt64(data.ResourceDisk), - 109: resources_core.FormatString(data.ResourceRealm), - 227: resources_core.FormatInt64(data.ResourceInstances), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 81, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 81, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *SupersetResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 81, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *SupersetResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan SupersetModel - var state SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 81, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *SupersetResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *SupersetResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *SupersetResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/82_harbor_resource.go b/generated/dev/go/82_harbor_resource.go deleted file mode 100644 index 43a76f0..0000000 --- a/generated/dev/go/82_harbor_resource.go +++ /dev/null @@ -1,457 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: harbor -// Service ID: 82 - -var _ resource.Resource = &HarborResource{} -var _ resource.ResourceWithModifyPlan = &HarborResource{} -var _ resource.ResourceWithImportState = &HarborResource{} - -type HarborResource struct { - client *core.UniversalClient -} - -type HarborModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - Emails types.String `tfsdk:"emails"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewHarborResource() resource.Resource { - return &HarborResource{} -} - -func (r *HarborResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_harbor" -} - -func (r *HarborResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "emails": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("testuser1"), MarkdownDescription: "Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID экземпляра услуги S3 Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *HarborResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *HarborModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() { - plan.S3Uid = types.StringValue(resolvedS3Uid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Emails.IsNull() && !plan.Emails.IsUnknown() && !state.Emails.IsNull() && !state.Emails.IsUnknown() { - if plan.Emails.ValueString() != state.Emails.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить emails", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - if plan.S3Uid.ValueString() != state.S3Uid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 16: resources_core.FormatString(config.Domain), - 17: resources_core.FormatString(config.Emails), - 110: resources_core.FormatString(config.ResourceRealm), - 228: resources_core.FormatInt64(config.ResourceCPU), - 229: resources_core.FormatInt64(config.ResourceMemory), - 230: resources_core.FormatInt64(config.ResourceInstances), - 231: resources_core.FormatString(config.S3Uid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 82, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *HarborResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 82, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 16: resources_core.FormatString(data.Domain), - 17: resources_core.FormatString(data.Emails), - 110: resources_core.FormatString(data.ResourceRealm), - 228: resources_core.FormatInt64(data.ResourceCPU), - 229: resources_core.FormatInt64(data.ResourceMemory), - 230: resources_core.FormatInt64(data.ResourceInstances), - 231: resources_core.FormatString(data.S3Uid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 82, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 82, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HarborResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 82, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *HarborResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan HarborModel - var state HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 82, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HarborResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *HarborResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *HarborResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/88_k8s_ziti_controller_resource.go b/generated/dev/go/88_k8s_ziti_controller_resource.go deleted file mode 100644 index e283c47..0000000 --- a/generated/dev/go/88_k8s_ziti_controller_resource.go +++ /dev/null @@ -1,415 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_ziti_controller -// Service ID: 88 - -var _ resource.Resource = &K8sZitiControllerResource{} -var _ resource.ResourceWithModifyPlan = &K8sZitiControllerResource{} -var _ resource.ResourceWithImportState = &K8sZitiControllerResource{} - -type K8sZitiControllerResource struct { - client *core.UniversalClient -} - -type K8sZitiControllerModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewK8sZitiControllerResource() resource.Resource { - return &K8sZitiControllerResource{} -} - -func (r *K8sZitiControllerResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_ziti_controller" -} - -func (r *K8sZitiControllerResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores) Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sZitiControllerResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *K8sZitiControllerModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 294: resources_core.FormatInt64(config.ResourceCPU), - 295: resources_core.FormatInt64(config.ResourceMemory), - 296: resources_core.FormatInt64(config.ResourceDisk), - 297: resources_core.FormatInt64(config.ResourceInstances), - 298: resources_core.FormatString(config.ResourceRealm), - 299: resources_core.FormatString(config.Domain), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 88, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *K8sZitiControllerResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 88, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 294: resources_core.FormatInt64(data.ResourceCPU), - 295: resources_core.FormatInt64(data.ResourceMemory), - 296: resources_core.FormatInt64(data.ResourceDisk), - 297: resources_core.FormatInt64(data.ResourceInstances), - 298: resources_core.FormatString(data.ResourceRealm), - 299: resources_core.FormatString(data.Domain), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 88, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 88, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sZitiControllerResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 88, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *K8sZitiControllerResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sZitiControllerModel - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 88, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sZitiControllerResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *K8sZitiControllerResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *K8sZitiControllerResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/89_flask_resource.go b/generated/dev/go/89_flask_resource.go deleted file mode 100644 index 04646aa..0000000 --- a/generated/dev/go/89_flask_resource.go +++ /dev/null @@ -1,465 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: flask -// Service ID: 89 - -var _ resource.Resource = &FlaskResource{} -var _ resource.ResourceWithModifyPlan = &FlaskResource{} -var _ resource.ResourceWithImportState = &FlaskResource{} - -type FlaskResource struct { - client *core.UniversalClient -} - -type FlaskModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - GitPath types.String `tfsdk:"git_path"` - HealthPath types.String `tfsdk:"health_path"` - JsonEnv types.String `tfsdk:"json_env"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewFlaskResource() resource.Resource { - return &FlaskResource{} -} - -func (r *FlaskResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_flask" -} - -func (r *FlaskResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан `FQDN`, то происходят проверки DNS на валидность А-записи. А-запись **обязана смотреть на балансировщик** ресурсной платформы.
Если указано имя `в рамках одного октета`, будет добавлено **в публичную днс-зону** Не изменяется после создания."}, - "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/Foxyhhd/Baldurs-Gate-test.git"), MarkdownDescription: "Пример: `https://github.com/myuser/myproject.git`"}, - "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `/api/v1/health` Не изменяется после создания."}, - "json_env": schema.StringAttribute{Optional: true, MarkdownDescription: "Структура, которая будет передана как переменные окружения"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Пример: `1000`"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `3`"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(256), MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Кластер Kubernetes в котором будет развёрнуто приложение Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *FlaskResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *FlaskModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() { - if plan.HealthPath.ValueString() != state.HealthPath.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить health_path", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 248: resources_core.FormatString(config.Domain), - 249: resources_core.FormatString(config.ResourceRealm), - 250: resources_core.FormatInt64(config.ResourceCPU), - 251: resources_core.FormatInt64(config.ResourceMemory), - 252: resources_core.FormatInt64(config.ResourceInstances), - 253: resources_core.FormatString(config.GitPath), - 254: resources_core.FormatString(config.JsonEnv), - 255: resources_core.FormatString(config.HealthPath), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 89, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *FlaskResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 89, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 248: resources_core.FormatString(data.Domain), - 249: resources_core.FormatString(data.ResourceRealm), - 250: resources_core.FormatInt64(data.ResourceCPU), - 251: resources_core.FormatInt64(data.ResourceMemory), - 252: resources_core.FormatInt64(data.ResourceInstances), - 253: resources_core.FormatString(data.GitPath), - 254: resources_core.FormatString(data.JsonEnv), - 255: resources_core.FormatString(data.HealthPath), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 89, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 89, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *FlaskResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 89, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *FlaskResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan FlaskModel - var state FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() { - if plan.GitPath.ValueString() != state.GitPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 451: resources_core.FormatInt64(plan.ResourceCPU), - 452: resources_core.FormatInt64(plan.ResourceMemory), - 453: resources_core.FormatInt64(plan.ResourceInstances), - 454: resources_core.FormatString(plan.GitPath), - 455: resources_core.FormatString(plan.JsonEnv), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 89, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *FlaskResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *FlaskResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *FlaskResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/90_postgres_database_resource.go b/generated/dev/go/90_postgres_database_resource.go deleted file mode 100644 index 80ef7e6..0000000 --- a/generated/dev/go/90_postgres_database_resource.go +++ /dev/null @@ -1,362 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Subresource: database - -var _ resource.Resource = &PostgresDatabaseResource{} - -// PostgresDatabaseResource manages a subresource via operations. -type PostgresDatabaseResource struct { - client *core.UniversalClient -} - -type PostgresDatabaseModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DbName types.String `tfsdk:"db_name"` - DbOwner types.String `tfsdk:"db_owner"` -} - -func NewPostgresDatabaseResource() resource.Resource { - return &PostgresDatabaseResource{} -} - -func (r *PostgresDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_database" -} - -func (r *PostgresDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "postgres_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "db_name": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "db_owner": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.DbName.IsNull() || plan.DbName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "db_name is required.") - return - } - if plan.DbOwner.IsNull() || plan.DbOwner.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "db_owner is required.") - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - "dbOwner": resources_core.FormatString(plan.DbOwner), - } - identityCodes := []string{ - "dbName", - "dbOwner", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - "dbOwner": resources_core.FormatString(plan.DbOwner), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state PostgresDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - "dbOwner": resources_core.FormatString(plan.DbOwner), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PostgresDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_database" == "" { - return - } - - instanceUID := strings.TrimSpace(state.PostgresID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "dbName": resources_core.FormatString(state.DbName), - "dbOwner": resources_core.FormatString(state.DbOwner), - } - identityCodes := []string{ - "dbName", - "dbOwner", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "dbName": resources_core.FormatString(state.DbName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_database", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *PostgresDatabaseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/90_postgres_recovery_action.go b/generated/dev/go/90_postgres_recovery_action.go deleted file mode 100644 index afef981..0000000 --- a/generated/dev/go/90_postgres_recovery_action.go +++ /dev/null @@ -1,163 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Action: recovery - -var _ resource.Resource = &PostgresRecoveryResource{} - -// PostgresRecoveryResource triggers a one-time action. -type PostgresRecoveryResource struct { - client *core.UniversalClient -} - -type PostgresRecoveryModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewPostgresRecoveryResource() resource.Resource { - return &PostgresRecoveryResource{} -} - -func (r *PostgresRecoveryResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_recovery" -} - -func (r *PostgresRecoveryResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "postgres_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)
"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili)
"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresRecoveryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresRecoveryModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceInstances": resources_core.FormatInt64(plan.ResourceInstances), - "resourceMemory": resources_core.FormatInt64(plan.ResourceMemory), - "resourceCPU": resources_core.FormatInt64(plan.ResourceCPU), - "resourceDisk": resources_core.FormatInt64(plan.ResourceDisk), - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "recovery", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "recovery", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresRecoveryResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresRecoveryModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresRecoveryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresRecoveryModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceInstances": resources_core.FormatInt64(plan.ResourceInstances), - "resourceMemory": resources_core.FormatInt64(plan.ResourceMemory), - "resourceCPU": resources_core.FormatInt64(plan.ResourceCPU), - "resourceDisk": resources_core.FormatInt64(plan.ResourceDisk), - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "recovery", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "recovery", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresRecoveryResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *PostgresRecoveryResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/90_postgres_resource.go b/generated/dev/go/90_postgres_resource.go deleted file mode 100644 index 5b2413e..0000000 --- a/generated/dev/go/90_postgres_resource.go +++ /dev/null @@ -1,698 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Service ID: 90 - -var _ resource.Resource = &PostgresResource{} -var _ resource.ResourceWithModifyPlan = &PostgresResource{} -var _ resource.ResourceWithImportState = &PostgresResource{} - -type PostgresResource struct { - client *core.UniversalClient -} - -type PostgresModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AllowNoSSL types.Bool `tfsdk:"allow_no_s_s_l"` - AppVersion types.String `tfsdk:"app_version"` - AutoScale types.Bool `tfsdk:"auto_scale"` - AutoScalePercentage types.Int64 `tfsdk:"auto_scale_percentage"` - AutoScaleQuotaGb types.String `tfsdk:"auto_scale_quota_gb"` - AutoScaleTechWindow types.Int64 `tfsdk:"auto_scale_tech_window"` - EnablePgPoolerMaster types.Bool `tfsdk:"enable_pg_pooler_master"` - EnablePgPoolerSlave types.Bool `tfsdk:"enable_pg_pooler_slave"` - ExtBACKUPNUMTORETAIN types.Int64 `tfsdk:"ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n"` - ExtBACKUPSCHEDULE types.String `tfsdk:"ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - IpSpaceNameSlave types.String `tfsdk:"ip_space_name_slave"` - JsonParameters types.String `tfsdk:"json_parameters"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - NeedExternalAddressSlave types.Bool `tfsdk:"need_external_address_slave"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.String `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewPostgresResource() resource.Resource { - return &PostgresResource{} -} - -func (r *PostgresResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres" -} - -func (r *PostgresResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "allow_no_s_s_l": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр"}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("17"), MarkdownDescription: "Версия PostgreSQL"}, - "auto_scale": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги Не изменяется после создания."}, - "auto_scale_percentage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема Не изменяется после создания."}, - "auto_scale_quota_gb": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("1"), MarkdownDescription: "Квота для autoScale Не изменяется после создания."}, - "auto_scale_tech_window": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) Не изменяется после создания."}, - "enable_pg_pooler_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает pgPooler (на запись). Будет создан новый под"}, - "enable_pg_pooler_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает pgPooler (на чтение). Будет создан новый под"}, - "ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(7), MarkdownDescription: "Не обязательный. Количество сохраняемых бекапов"}, - "ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("0 0 * * *"), MarkdownDescription: "Не обязательный. Время запуска бекапа"}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`"}, - "ip_space_name_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave"}, - "json_parameters": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{ \"log_connections\": \"off\", \"log_disconnections\": \"off\" }"), MarkdownDescription: "Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к master"}, - "need_external_address_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores)"}, - "resource_disk": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("10"), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *PostgresModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() { - plan.S3Uid = types.StringValue(resolvedS3Uid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AutoScale.IsNull() && !plan.AutoScale.IsUnknown() && !state.AutoScale.IsNull() && !state.AutoScale.IsUnknown() { - if plan.AutoScale.ValueBool() != state.AutoScale.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить auto_scale", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.AutoScalePercentage.IsNull() && !plan.AutoScalePercentage.IsUnknown() && !state.AutoScalePercentage.IsNull() && !state.AutoScalePercentage.IsUnknown() { - if plan.AutoScalePercentage.ValueInt64() != state.AutoScalePercentage.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить auto_scale_percentage", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.AutoScaleQuotaGb.IsNull() && !plan.AutoScaleQuotaGb.IsUnknown() && !state.AutoScaleQuotaGb.IsNull() && !state.AutoScaleQuotaGb.IsUnknown() { - if plan.AutoScaleQuotaGb.ValueString() != state.AutoScaleQuotaGb.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить auto_scale_quota_gb", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.AutoScaleTechWindow.IsNull() && !plan.AutoScaleTechWindow.IsUnknown() && !state.AutoScaleTechWindow.IsNull() && !state.AutoScaleTechWindow.IsUnknown() { - if plan.AutoScaleTechWindow.ValueInt64() != state.AutoScaleTechWindow.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить auto_scale_tech_window", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - if plan.S3Uid.ValueString() != state.S3Uid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 23: resources_core.FormatString(config.S3Uid), - 80: resources_core.FormatInt64(config.ResourceInstances), - 81: resources_core.FormatInt64(config.ResourceMemory), - 82: resources_core.FormatInt64(config.ResourceCPU), - 83: resources_core.FormatString(config.ResourceDisk), - 102: resources_core.FormatString(config.ResourceRealm), - 145: resources_core.FormatBool(config.NeedExternalAddressMaster), - 146: resources_core.FormatBool(config.NeedExternalAddressSlave), - 265: resources_core.FormatString(config.ExtBACKUPSCHEDULE), - 266: resources_core.FormatInt64(config.ExtBACKUPNUMTORETAIN), - 310: resources_core.FormatString(config.AppVersion), - 311: resources_core.FormatString(config.JsonParameters), - 312: resources_core.FormatBool(config.EnablePgPoolerMaster), - 313: resources_core.FormatBool(config.EnablePgPoolerSlave), - 314: resources_core.FormatBool(config.AllowNoSSL), - 329: resources_core.FormatBool(config.AutoScale), - 330: resources_core.FormatInt64(config.AutoScalePercentage), - 331: resources_core.FormatInt64(config.AutoScaleTechWindow), - 337: resources_core.FormatString(config.IpSpaceNameMaster), - 338: resources_core.FormatString(config.IpSpaceNameSlave), - 339: resources_core.FormatString(config.AutoScaleQuotaGb), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 90, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *PostgresResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 90, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 23: resources_core.FormatString(data.S3Uid), - 80: resources_core.FormatInt64(data.ResourceInstances), - 81: resources_core.FormatInt64(data.ResourceMemory), - 82: resources_core.FormatInt64(data.ResourceCPU), - 83: resources_core.FormatString(data.ResourceDisk), - 102: resources_core.FormatString(data.ResourceRealm), - 145: resources_core.FormatBool(data.NeedExternalAddressMaster), - 146: resources_core.FormatBool(data.NeedExternalAddressSlave), - 265: resources_core.FormatString(data.ExtBACKUPSCHEDULE), - 266: resources_core.FormatInt64(data.ExtBACKUPNUMTORETAIN), - 310: resources_core.FormatString(data.AppVersion), - 311: resources_core.FormatString(data.JsonParameters), - 312: resources_core.FormatBool(data.EnablePgPoolerMaster), - 313: resources_core.FormatBool(data.EnablePgPoolerSlave), - 314: resources_core.FormatBool(data.AllowNoSSL), - 329: resources_core.FormatBool(data.AutoScale), - 330: resources_core.FormatInt64(data.AutoScalePercentage), - 331: resources_core.FormatInt64(data.AutoScaleTechWindow), - 337: resources_core.FormatString(data.IpSpaceNameMaster), - 338: resources_core.FormatString(data.IpSpaceNameSlave), - 339: resources_core.FormatString(data.AutoScaleQuotaGb), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 90, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 90, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"}, - {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "jsonParameters", Field: "JsonParameters", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 90, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"}, - {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "jsonParameters", Field: "JsonParameters", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *PostgresResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresModel - var state PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueString() != state.ResourceDisk.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressSlave.IsNull() != state.NeedExternalAddressSlave.IsNull() || plan.NeedExternalAddressSlave.IsUnknown() != state.NeedExternalAddressSlave.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressSlave.IsNull() && !plan.NeedExternalAddressSlave.IsUnknown() && !state.NeedExternalAddressSlave.IsNull() && !state.NeedExternalAddressSlave.IsUnknown() { - if plan.NeedExternalAddressSlave.ValueBool() != state.NeedExternalAddressSlave.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPSCHEDULE.IsNull() != state.ExtBACKUPSCHEDULE.IsNull() || plan.ExtBACKUPSCHEDULE.IsUnknown() != state.ExtBACKUPSCHEDULE.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPSCHEDULE.IsNull() && !plan.ExtBACKUPSCHEDULE.IsUnknown() && !state.ExtBACKUPSCHEDULE.IsNull() && !state.ExtBACKUPSCHEDULE.IsUnknown() { - if plan.ExtBACKUPSCHEDULE.ValueString() != state.ExtBACKUPSCHEDULE.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPNUMTORETAIN.IsNull() != state.ExtBACKUPNUMTORETAIN.IsNull() || plan.ExtBACKUPNUMTORETAIN.IsUnknown() != state.ExtBACKUPNUMTORETAIN.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPNUMTORETAIN.IsNull() && !plan.ExtBACKUPNUMTORETAIN.IsUnknown() && !state.ExtBACKUPNUMTORETAIN.IsNull() && !state.ExtBACKUPNUMTORETAIN.IsUnknown() { - if plan.ExtBACKUPNUMTORETAIN.ValueInt64() != state.ExtBACKUPNUMTORETAIN.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonParameters.IsNull() != state.JsonParameters.IsNull() || plan.JsonParameters.IsUnknown() != state.JsonParameters.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonParameters.IsNull() && !plan.JsonParameters.IsUnknown() && !state.JsonParameters.IsNull() && !state.JsonParameters.IsUnknown() { - if plan.JsonParameters.ValueString() != state.JsonParameters.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.EnablePgPoolerMaster.IsNull() != state.EnablePgPoolerMaster.IsNull() || plan.EnablePgPoolerMaster.IsUnknown() != state.EnablePgPoolerMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.EnablePgPoolerMaster.IsNull() && !plan.EnablePgPoolerMaster.IsUnknown() && !state.EnablePgPoolerMaster.IsNull() && !state.EnablePgPoolerMaster.IsUnknown() { - if plan.EnablePgPoolerMaster.ValueBool() != state.EnablePgPoolerMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.EnablePgPoolerSlave.IsNull() != state.EnablePgPoolerSlave.IsNull() || plan.EnablePgPoolerSlave.IsUnknown() != state.EnablePgPoolerSlave.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.EnablePgPoolerSlave.IsNull() && !plan.EnablePgPoolerSlave.IsUnknown() && !state.EnablePgPoolerSlave.IsNull() && !state.EnablePgPoolerSlave.IsUnknown() { - if plan.EnablePgPoolerSlave.ValueBool() != state.EnablePgPoolerSlave.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AllowNoSSL.IsNull() != state.AllowNoSSL.IsNull() || plan.AllowNoSSL.IsUnknown() != state.AllowNoSSL.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AllowNoSSL.IsNull() && !plan.AllowNoSSL.IsUnknown() && !state.AllowNoSSL.IsNull() && !state.AllowNoSSL.IsUnknown() { - if plan.AllowNoSSL.ValueBool() != state.AllowNoSSL.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameSlave.IsNull() != state.IpSpaceNameSlave.IsNull() || plan.IpSpaceNameSlave.IsUnknown() != state.IpSpaceNameSlave.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameSlave.IsNull() && !plan.IpSpaceNameSlave.IsUnknown() && !state.IpSpaceNameSlave.IsNull() && !state.IpSpaceNameSlave.IsUnknown() { - if plan.IpSpaceNameSlave.ValueString() != state.IpSpaceNameSlave.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 91: resources_core.FormatInt64(plan.ResourceInstances), - 92: resources_core.FormatInt64(plan.ResourceMemory), - 93: resources_core.FormatInt64(plan.ResourceCPU), - 94: resources_core.FormatString(plan.ResourceDisk), - 147: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 148: resources_core.FormatBool(plan.NeedExternalAddressSlave), - 267: resources_core.FormatString(plan.ExtBACKUPSCHEDULE), - 268: resources_core.FormatInt64(plan.ExtBACKUPNUMTORETAIN), - 315: resources_core.FormatString(plan.AppVersion), - 316: resources_core.FormatString(plan.JsonParameters), - 317: resources_core.FormatBool(plan.EnablePgPoolerMaster), - 318: resources_core.FormatBool(plan.EnablePgPoolerSlave), - 319: resources_core.FormatBool(plan.AllowNoSSL), - 541: resources_core.FormatString(plan.IpSpaceNameMaster), - 542: resources_core.FormatString(plan.IpSpaceNameSlave), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 90, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"}, - {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "jsonParameters", Field: "JsonParameters", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *PostgresResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *PostgresResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/90_postgres_restart_action.go b/generated/dev/go/90_postgres_restart_action.go deleted file mode 100644 index 38ce584..0000000 --- a/generated/dev/go/90_postgres_restart_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Action: restart - -var _ resource.Resource = &PostgresRestartResource{} - -// PostgresRestartResource triggers a one-time action. -type PostgresRestartResource struct { - client *core.UniversalClient -} - -type PostgresRestartModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewPostgresRestartResource() resource.Resource { - return &PostgresRestartResource{} -} - -func (r *PostgresRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_restart" -} - -func (r *PostgresRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "postgres_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresRestartModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *PostgresRestartResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/90_postgres_user_resource.go b/generated/dev/go/90_postgres_user_resource.go deleted file mode 100644 index 05ed7f4..0000000 --- a/generated/dev/go/90_postgres_user_resource.go +++ /dev/null @@ -1,362 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Subresource: user - -var _ resource.Resource = &PostgresUserResource{} - -// PostgresUserResource manages a subresource via operations. -type PostgresUserResource struct { - client *core.UniversalClient -} - -type PostgresUserModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Role types.String `tfsdk:"role"` - Username types.String `tfsdk:"username"` -} - -func NewPostgresUserResource() resource.Resource { - return &PostgresUserResource{} -} - -func (r *PostgresUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_user" -} - -func (r *PostgresUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "postgres_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "role": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать роль из списка Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.Role.IsNull() || plan.Role.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "role is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "role": resources_core.FormatString(plan.Role), - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "role", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "role": resources_core.FormatString(plan.Role), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state PostgresUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "role": resources_core.FormatString(plan.Role), - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PostgresUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.PostgresID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "role": resources_core.FormatString(state.Role), - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "role", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *PostgresUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/91_redis_resource.go b/generated/dev/go/91_redis_resource.go deleted file mode 100644 index 157507b..0000000 --- a/generated/dev/go/91_redis_resource.go +++ /dev/null @@ -1,447 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: redis -// Service ID: 91 - -var _ resource.Resource = &RedisResource{} -var _ resource.ResourceWithModifyPlan = &RedisResource{} -var _ resource.ResourceWithImportState = &RedisResource{} - -type RedisResource struct { - client *core.UniversalClient -} - -type RedisModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - IpSpaceNameSlave types.String `tfsdk:"ip_space_name_slave"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - NeedExternalAddressSlave types.Bool `tfsdk:"need_external_address_slave"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewRedisResource() resource.Resource { - return &RedisResource{} -} - -func (r *RedisResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_redis" -} - -func (r *RedisResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster Не изменяется после создания."}, - "ip_space_name_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave Не изменяется после создания."}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний IP для доступа к master Не изменяется после создания."}, - "need_external_address_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Квота ядра пода (Указывается в mili) Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(30), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *RedisResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *RedisModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name_master", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.IpSpaceNameSlave.IsNull() && !plan.IpSpaceNameSlave.IsUnknown() && !state.IpSpaceNameSlave.IsNull() && !state.IpSpaceNameSlave.IsUnknown() { - if plan.IpSpaceNameSlave.ValueString() != state.IpSpaceNameSlave.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name_slave", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_master", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressSlave.IsNull() && !plan.NeedExternalAddressSlave.IsUnknown() && !state.NeedExternalAddressSlave.IsNull() && !state.NeedExternalAddressSlave.IsUnknown() { - if plan.NeedExternalAddressSlave.ValueBool() != state.NeedExternalAddressSlave.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_slave", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 112: resources_core.FormatInt64(config.ResourceCPU), - 113: resources_core.FormatInt64(config.ResourceMemory), - 114: resources_core.FormatInt64(config.ResourceDisk), - 181: resources_core.FormatInt64(config.ResourceInstances), - 182: resources_core.FormatString(config.ResourceRealm), - 183: resources_core.FormatBool(config.NeedExternalAddressMaster), - 184: resources_core.FormatBool(config.NeedExternalAddressSlave), - 548: resources_core.FormatString(config.IpSpaceNameMaster), - 549: resources_core.FormatString(config.IpSpaceNameSlave), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 91, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *RedisResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 91, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 112: resources_core.FormatInt64(data.ResourceCPU), - 113: resources_core.FormatInt64(data.ResourceMemory), - 114: resources_core.FormatInt64(data.ResourceDisk), - 181: resources_core.FormatInt64(data.ResourceInstances), - 182: resources_core.FormatString(data.ResourceRealm), - 183: resources_core.FormatBool(data.NeedExternalAddressMaster), - 184: resources_core.FormatBool(data.NeedExternalAddressSlave), - 548: resources_core.FormatString(data.IpSpaceNameMaster), - 549: resources_core.FormatString(data.IpSpaceNameSlave), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 91, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 91, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RedisResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 91, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *RedisResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan RedisModel - var state RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 91, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RedisResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *RedisResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *RedisResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/92_mongodb_resource.go b/generated/dev/go/92_mongodb_resource.go deleted file mode 100644 index 1e1ccaa..0000000 --- a/generated/dev/go/92_mongodb_resource.go +++ /dev/null @@ -1,480 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mongodb -// Service ID: 92 - -var _ resource.Resource = &MongodbResource{} -var _ resource.ResourceWithModifyPlan = &MongodbResource{} -var _ resource.ResourceWithImportState = &MongodbResource{} - -type MongodbResource struct { - client *core.UniversalClient -} - -type MongodbModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewMongodbResource() resource.Resource { - return &MongodbResource{} -} - -func (r *MongodbResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mongodb" -} - -func (r *MongodbResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`"}, - "resource_c_p_u": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `1000`"}, - "resource_disk": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `20`"}, - "resource_instances": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2`"}, - "resource_memory": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MongodbResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *MongodbModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceCPU.IsNull() || config.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if config.ResourceDisk.IsNull() || config.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if config.ResourceInstances.IsNull() || config.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if config.ResourceMemory.IsNull() || config.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 487: resources_core.FormatInt64(config.ResourceInstances), - 588: resources_core.FormatInt64(config.ResourceMemory), - 589: resources_core.FormatInt64(config.ResourceCPU), - 590: resources_core.FormatInt64(config.ResourceDisk), - 595: resources_core.FormatString(config.ResourceRealm), - 645: resources_core.FormatBool(config.NeedExternalAddressMaster), - 646: resources_core.FormatString(config.IpSpaceNameMaster), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 92, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *MongodbResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceCPU.IsNull() || data.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if data.ResourceDisk.IsNull() || data.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if data.ResourceInstances.IsNull() || data.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if data.ResourceMemory.IsNull() || data.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 92, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 487: resources_core.FormatInt64(data.ResourceInstances), - 588: resources_core.FormatInt64(data.ResourceMemory), - 589: resources_core.FormatInt64(data.ResourceCPU), - 590: resources_core.FormatInt64(data.ResourceDisk), - 595: resources_core.FormatString(data.ResourceRealm), - 645: resources_core.FormatBool(data.NeedExternalAddressMaster), - 646: resources_core.FormatString(data.IpSpaceNameMaster), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 92, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 92, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 92, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *MongodbResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MongodbModel - var state MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 648: resources_core.FormatInt64(plan.ResourceInstances), - 649: resources_core.FormatInt64(plan.ResourceMemory), - 650: resources_core.FormatInt64(plan.ResourceCPU), - 651: resources_core.FormatInt64(plan.ResourceDisk), - 652: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 653: resources_core.FormatString(plan.IpSpaceNameMaster), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 92, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *MongodbResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *MongodbResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/92_mongodb_user_resource.go b/generated/dev/go/92_mongodb_user_resource.go deleted file mode 100644 index cdd8684..0000000 --- a/generated/dev/go/92_mongodb_user_resource.go +++ /dev/null @@ -1,368 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mongodb -// Subresource: user - -var _ resource.Resource = &MongodbUserResource{} - -// MongodbUserResource manages a subresource via operations. -type MongodbUserResource struct { - client *core.UniversalClient -} - -type MongodbUserModel struct { - ID types.String `tfsdk:"id"` - MongodbID types.String `tfsdk:"mongodb_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DbName types.String `tfsdk:"db_name"` - Role types.String `tfsdk:"role"` - Username types.String `tfsdk:"username"` -} - -func NewMongodbUserResource() resource.Resource { - return &MongodbUserResource{} -} - -func (r *MongodbUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mongodb_user" -} - -func (r *MongodbUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "mongodb_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "db_name": schema.StringAttribute{Required: true}, - "role": schema.StringAttribute{Required: true}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MongodbUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan MongodbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.DbName.IsNull() || plan.DbName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "db_name is required.") - return - } - if plan.Role.IsNull() || plan.Role.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "role is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.MongodbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "dbName": resources_core.FormatString(plan.DbName), - "role": resources_core.FormatString(plan.Role), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MongodbUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MongodbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_user" == "" { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.MongodbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "dbName": resources_core.FormatString(plan.DbName), - "role": resources_core.FormatString(plan.Role), - }) - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_user", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MongodbUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.MongodbID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *MongodbUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/93_rabbitmq_resource.go b/generated/dev/go/93_rabbitmq_resource.go deleted file mode 100644 index 87d44f2..0000000 --- a/generated/dev/go/93_rabbitmq_resource.go +++ /dev/null @@ -1,449 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: rabbitmq -// Service ID: 93 - -var _ resource.Resource = &RabbitmqResource{} -var _ resource.ResourceWithModifyPlan = &RabbitmqResource{} -var _ resource.ResourceWithImportState = &RabbitmqResource{} - -type RabbitmqResource struct { - client *core.UniversalClient -} - -type RabbitmqModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewRabbitmqResource() resource.Resource { - return &RabbitmqResource{} -} - -func (r *RabbitmqResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_rabbitmq" -} - -func (r *RabbitmqResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Пример: `2000`"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(30), MarkdownDescription: "Пример: `20`"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1124), MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *RabbitmqResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *RabbitmqModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 116: resources_core.FormatInt64(config.ResourceCPU), - 117: resources_core.FormatInt64(config.ResourceMemory), - 118: resources_core.FormatInt64(config.ResourceDisk), - 119: resources_core.FormatString(config.ResourceRealm), - 224: resources_core.FormatInt64(config.ResourceInstances), - 225: resources_core.FormatBool(config.NeedExternalAddressMaster), - 543: resources_core.FormatString(config.IpSpaceNameMaster), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 93, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *RabbitmqResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 93, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 116: resources_core.FormatInt64(data.ResourceCPU), - 117: resources_core.FormatInt64(data.ResourceMemory), - 118: resources_core.FormatInt64(data.ResourceDisk), - 119: resources_core.FormatString(data.ResourceRealm), - 224: resources_core.FormatInt64(data.ResourceInstances), - 225: resources_core.FormatBool(data.NeedExternalAddressMaster), - 543: resources_core.FormatString(data.IpSpaceNameMaster), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 93, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 93, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RabbitmqResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 93, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *RabbitmqResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan RabbitmqModel - var state RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 304: resources_core.FormatInt64(plan.ResourceCPU), - 305: resources_core.FormatInt64(plan.ResourceMemory), - 306: resources_core.FormatInt64(plan.ResourceDisk), - 307: resources_core.FormatInt64(plan.ResourceInstances), - 308: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 545: resources_core.FormatString(plan.IpSpaceNameMaster), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 93, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RabbitmqResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *RabbitmqResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *RabbitmqResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/94_lucee_redeploy_action.go b/generated/dev/go/94_lucee_redeploy_action.go deleted file mode 100644 index d9bce0b..0000000 --- a/generated/dev/go/94_lucee_redeploy_action.go +++ /dev/null @@ -1,146 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: lucee -// Action: redeploy - -var _ resource.Resource = &LuceeRedeployResource{} - -// LuceeRedeployResource triggers a one-time action. -type LuceeRedeployResource struct { - client *core.UniversalClient -} - -type LuceeRedeployModel struct { - ID types.String `tfsdk:"id"` - LuceeID types.String `tfsdk:"lucee_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewLuceeRedeployResource() resource.Resource { - return &LuceeRedeployResource{} -} - -func (r *LuceeRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_lucee_redeploy" -} - -func (r *LuceeRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "lucee_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *LuceeRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan LuceeRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.LuceeID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *LuceeRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state LuceeRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan LuceeRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.LuceeID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *LuceeRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *LuceeRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/94_lucee_resource.go b/generated/dev/go/94_lucee_resource.go deleted file mode 100644 index 30f3ffd..0000000 --- a/generated/dev/go/94_lucee_resource.go +++ /dev/null @@ -1,487 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: lucee -// Service ID: 94 - -var _ resource.Resource = &LuceeResource{} -var _ resource.ResourceWithModifyPlan = &LuceeResource{} -var _ resource.ResourceWithImportState = &LuceeResource{} - -type LuceeResource struct { - client *core.UniversalClient -} - -type LuceeModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AppVersion types.String `tfsdk:"app_version"` - Domain types.String `tfsdk:"domain"` - GitPath types.String `tfsdk:"git_path"` - HealthPath types.String `tfsdk:"health_path"` - JsonEnv types.String `tfsdk:"json_env"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewLuceeResource() resource.Resource { - return &LuceeResource{} -} - -func (r *LuceeResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_lucee" -} - -func (r *LuceeResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("5.4"), MarkdownDescription: "Версия Lucee"}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("lucee-"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/xahys/testlucee"), MarkdownDescription: "Путь до Git, который будет webroot для сайта"}, - "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код"}, - "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{ \"param\": \"value\" }"), MarkdownDescription: "Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения.", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *LuceeResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *LuceeModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 103: resources_core.FormatString(config.Domain), - 104: resources_core.FormatString(config.GitPath), - 105: resources_core.FormatString(config.JsonEnv), - 106: resources_core.FormatInt64(config.ResourceCPU), - 107: resources_core.FormatInt64(config.ResourceMemory), - 108: resources_core.FormatString(config.ResourceRealm), - 132: resources_core.FormatString(config.HealthPath), - 139: resources_core.FormatInt64(config.ResourceInstances), - 263: resources_core.FormatString(config.AppVersion), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 94, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *LuceeResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 94, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 103: resources_core.FormatString(data.Domain), - 104: resources_core.FormatString(data.GitPath), - 105: resources_core.FormatString(data.JsonEnv), - 106: resources_core.FormatInt64(data.ResourceCPU), - 107: resources_core.FormatInt64(data.ResourceMemory), - 108: resources_core.FormatString(data.ResourceRealm), - 132: resources_core.FormatString(data.HealthPath), - 139: resources_core.FormatInt64(data.ResourceInstances), - 263: resources_core.FormatString(data.AppVersion), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 94, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 94, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 94, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *LuceeResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan LuceeModel - var state LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() { - if plan.GitPath.ValueString() != state.GitPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.HealthPath.IsNull() != state.HealthPath.IsNull() || plan.HealthPath.IsUnknown() != state.HealthPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() { - if plan.HealthPath.ValueString() != state.HealthPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 133: resources_core.FormatString(plan.GitPath), - 134: resources_core.FormatString(plan.HealthPath), - 135: resources_core.FormatString(plan.JsonEnv), - 136: resources_core.FormatInt64(plan.ResourceCPU), - 137: resources_core.FormatInt64(plan.ResourceMemory), - 138: resources_core.FormatInt64(plan.ResourceInstances), - 264: resources_core.FormatString(plan.AppVersion), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 94, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *LuceeResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *LuceeResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/94_lucee_restart_action.go b/generated/dev/go/94_lucee_restart_action.go deleted file mode 100644 index f7614f0..0000000 --- a/generated/dev/go/94_lucee_restart_action.go +++ /dev/null @@ -1,136 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: lucee -// Action: restart - -var _ resource.Resource = &LuceeRestartResource{} - -// LuceeRestartResource triggers a one-time action. -type LuceeRestartResource struct { - client *core.UniversalClient -} - -type LuceeRestartModel struct { - ID types.String `tfsdk:"id"` - LuceeID types.String `tfsdk:"lucee_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewLuceeRestartResource() resource.Resource { - return &LuceeRestartResource{} -} - -func (r *LuceeRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_lucee_restart" -} - -func (r *LuceeRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "lucee_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *LuceeRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan LuceeRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.LuceeID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *LuceeRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state LuceeRestartModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan LuceeRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.LuceeID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *LuceeRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *LuceeRestartResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/95_nodejs_redeploy_action.go b/generated/dev/go/95_nodejs_redeploy_action.go deleted file mode 100644 index 6d884ea..0000000 --- a/generated/dev/go/95_nodejs_redeploy_action.go +++ /dev/null @@ -1,146 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nodejs -// Action: redeploy - -var _ resource.Resource = &NodejsRedeployResource{} - -// NodejsRedeployResource triggers a one-time action. -type NodejsRedeployResource struct { - client *core.UniversalClient -} - -type NodejsRedeployModel struct { - ID types.String `tfsdk:"id"` - NodejsID types.String `tfsdk:"nodejs_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewNodejsRedeployResource() resource.Resource { - return &NodejsRedeployResource{} -} - -func (r *NodejsRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nodejs_redeploy" -} - -func (r *NodejsRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "nodejs_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NodejsRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan NodejsRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.NodejsID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NodejsRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NodejsRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NodejsRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NodejsRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.NodejsID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NodejsRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *NodejsRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/95_nodejs_resource.go b/generated/dev/go/95_nodejs_resource.go deleted file mode 100644 index 37b2799..0000000 --- a/generated/dev/go/95_nodejs_resource.go +++ /dev/null @@ -1,487 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nodejs -// Service ID: 95 - -var _ resource.Resource = &NodejsResource{} -var _ resource.ResourceWithModifyPlan = &NodejsResource{} -var _ resource.ResourceWithImportState = &NodejsResource{} - -type NodejsResource struct { - client *core.UniversalClient -} - -type NodejsModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AppVersion types.String `tfsdk:"app_version"` - Domain types.String `tfsdk:"domain"` - GitPath types.String `tfsdk:"git_path"` - HealthPath types.String `tfsdk:"health_path"` - JsonEnv types.String `tfsdk:"json_env"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNodejsResource() resource.Resource { - return &NodejsResource{} -} - -func (r *NodejsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nodejs" -} - -func (r *NodejsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("23"), MarkdownDescription: "Версия приложения"}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/xahys/testnode.git"), MarkdownDescription: "Путь до Git, который будет webroot для сайта"}, - "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет"}, - "json_env": schema.StringAttribute{Optional: true, MarkdownDescription: "Массив переменных, будут переданы в env приложения", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores). 1000Mili = 1 Ядро"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NodejsResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NodejsModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 149: resources_core.FormatString(config.Domain), - 150: resources_core.FormatString(config.GitPath), - 151: resources_core.FormatString(config.HealthPath), - 152: resources_core.FormatString(config.JsonEnv), - 153: resources_core.FormatInt64(config.ResourceCPU), - 154: resources_core.FormatInt64(config.ResourceMemory), - 155: resources_core.FormatInt64(config.ResourceInstances), - 156: resources_core.FormatString(config.ResourceRealm), - 270: resources_core.FormatString(config.AppVersion), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 95, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NodejsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 95, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 149: resources_core.FormatString(data.Domain), - 150: resources_core.FormatString(data.GitPath), - 151: resources_core.FormatString(data.HealthPath), - 152: resources_core.FormatString(data.JsonEnv), - 153: resources_core.FormatInt64(data.ResourceCPU), - 154: resources_core.FormatInt64(data.ResourceMemory), - 155: resources_core.FormatInt64(data.ResourceInstances), - 156: resources_core.FormatString(data.ResourceRealm), - 270: resources_core.FormatString(data.AppVersion), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 95, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 95, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NodejsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 95, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NodejsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NodejsModel - var state NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() { - if plan.GitPath.ValueString() != state.GitPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.HealthPath.IsNull() != state.HealthPath.IsNull() || plan.HealthPath.IsUnknown() != state.HealthPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() { - if plan.HealthPath.ValueString() != state.HealthPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 157: resources_core.FormatString(plan.GitPath), - 158: resources_core.FormatString(plan.HealthPath), - 159: resources_core.FormatString(plan.JsonEnv), - 160: resources_core.FormatInt64(plan.ResourceCPU), - 161: resources_core.FormatInt64(plan.ResourceMemory), - 162: resources_core.FormatInt64(plan.ResourceInstances), - 271: resources_core.FormatString(plan.AppVersion), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 95, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NodejsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NodejsResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NodejsResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/96_pgadmin_redeploy_action.go b/generated/dev/go/96_pgadmin_redeploy_action.go deleted file mode 100644 index b2bda6e..0000000 --- a/generated/dev/go/96_pgadmin_redeploy_action.go +++ /dev/null @@ -1,146 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: pgadmin -// Action: redeploy - -var _ resource.Resource = &PgadminRedeployResource{} - -// PgadminRedeployResource triggers a one-time action. -type PgadminRedeployResource struct { - client *core.UniversalClient -} - -type PgadminRedeployModel struct { - ID types.String `tfsdk:"id"` - PgadminID types.String `tfsdk:"pgadmin_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewPgadminRedeployResource() resource.Resource { - return &PgadminRedeployResource{} -} - -func (r *PgadminRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_pgadmin_redeploy" -} - -func (r *PgadminRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "pgadmin_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PgadminRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PgadminRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.PgadminID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PgadminRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PgadminRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PgadminRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PgadminRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PgadminID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PgadminRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *PgadminRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/96_pgadmin_resource.go b/generated/dev/go/96_pgadmin_resource.go deleted file mode 100644 index e7556b6..0000000 --- a/generated/dev/go/96_pgadmin_resource.go +++ /dev/null @@ -1,460 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: pgadmin -// Service ID: 96 - -var _ resource.Resource = &PgadminResource{} -var _ resource.ResourceWithModifyPlan = &PgadminResource{} -var _ resource.ResourceWithImportState = &PgadminResource{} - -type PgadminResource struct { - client *core.UniversalClient -} - -type PgadminModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - Login types.String `tfsdk:"login"` - Password types.String `tfsdk:"password"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewPgadminResource() resource.Resource { - return &PgadminResource{} -} - -func (r *PgadminResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_pgadmin" -} - -func (r *PgadminResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "login": schema.StringAttribute{Required: true, MarkdownDescription: "Логин для подключения к pgAdmin, в формате email (login@email.net) Не изменяется после создания."}, - "password": schema.StringAttribute{Required: true, MarkdownDescription: "Пароль для подключения к pgAdmin Не изменяется после создания.", Sensitive: true}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores). 1000Mili = 1 Ядро"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PgadminResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *PgadminModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Login.IsNull() && !plan.Login.IsUnknown() && !state.Login.IsNull() && !state.Login.IsUnknown() { - if plan.Login.ValueString() != state.Login.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить login", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Password.IsNull() && !plan.Password.IsUnknown() && !state.Password.IsNull() && !state.Password.IsUnknown() { - if plan.Password.ValueString() != state.Password.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить password", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Login.IsNull() || config.Login.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "login is required.") - return - } - if config.Password.IsNull() || config.Password.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "password is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 164: resources_core.FormatString(config.Domain), - 165: resources_core.FormatInt64(config.ResourceCPU), - 166: resources_core.FormatInt64(config.ResourceMemory), - 167: resources_core.FormatInt64(config.ResourceDisk), - 169: resources_core.FormatString(config.ResourceRealm), - 170: resources_core.FormatString(config.Login), - 171: resources_core.FormatString(config.Password), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 96, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *PgadminResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Login.IsNull() || data.Login.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "login is required.") - return - } - if data.Password.IsNull() || data.Password.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "password is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 96, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 164: resources_core.FormatString(data.Domain), - 165: resources_core.FormatInt64(data.ResourceCPU), - 166: resources_core.FormatInt64(data.ResourceMemory), - 167: resources_core.FormatInt64(data.ResourceDisk), - 169: resources_core.FormatString(data.ResourceRealm), - 170: resources_core.FormatString(data.Login), - 171: resources_core.FormatString(data.Password), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 96, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 96, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PgadminResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 96, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *PgadminResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PgadminModel - var state PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 172: resources_core.FormatInt64(plan.ResourceCPU), - 173: resources_core.FormatInt64(plan.ResourceMemory), - 174: resources_core.FormatInt64(plan.ResourceDisk), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 96, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PgadminResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *PgadminResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *PgadminResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/97_nodered_resource.go b/generated/dev/go/97_nodered_resource.go deleted file mode 100644 index 26074c9..0000000 --- a/generated/dev/go/97_nodered_resource.go +++ /dev/null @@ -1,422 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nodered -// Service ID: 97 - -var _ resource.Resource = &NoderedResource{} -var _ resource.ResourceWithModifyPlan = &NoderedResource{} -var _ resource.ResourceWithImportState = &NoderedResource{} - -type NoderedResource struct { - client *core.UniversalClient -} - -type NoderedModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNoderedResource() resource.Resource { - return &NoderedResource{} -} - -func (r *NoderedResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nodered" -} - -func (r *NoderedResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NoderedResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NoderedModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() || config.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 193: resources_core.FormatInt64(config.ResourceCPU), - 194: resources_core.FormatInt64(config.ResourceMemory), - 195: resources_core.FormatInt64(config.ResourceDisk), - 196: resources_core.FormatString(config.ResourceRealm), - 197: resources_core.FormatString(config.Domain), - 323: resources_core.FormatInt64(config.ResourceInstances), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 97, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NoderedResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 97, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 193: resources_core.FormatInt64(data.ResourceCPU), - 194: resources_core.FormatInt64(data.ResourceMemory), - 195: resources_core.FormatInt64(data.ResourceDisk), - 196: resources_core.FormatString(data.ResourceRealm), - 197: resources_core.FormatString(data.Domain), - 323: resources_core.FormatInt64(data.ResourceInstances), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 97, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 97, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NoderedResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 97, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NoderedResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NoderedModel - var state NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 97, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NoderedResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NoderedResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NoderedResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/98_http_redeploy_action.go b/generated/dev/go/98_http_redeploy_action.go deleted file mode 100644 index ef28e4b..0000000 --- a/generated/dev/go/98_http_redeploy_action.go +++ /dev/null @@ -1,146 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: http -// Action: redeploy - -var _ resource.Resource = &HttpRedeployResource{} - -// HttpRedeployResource triggers a one-time action. -type HttpRedeployResource struct { - client *core.UniversalClient -} - -type HttpRedeployModel struct { - ID types.String `tfsdk:"id"` - HttpID types.String `tfsdk:"http_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewHttpRedeployResource() resource.Resource { - return &HttpRedeployResource{} -} - -func (r *HttpRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_http_redeploy" -} - -func (r *HttpRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "http_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *HttpRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan HttpRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.HttpID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *HttpRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state HttpRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HttpRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan HttpRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.HttpID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *HttpRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *HttpRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/98_http_resource.go b/generated/dev/go/98_http_resource.go deleted file mode 100644 index 5750298..0000000 --- a/generated/dev/go/98_http_resource.go +++ /dev/null @@ -1,445 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: http -// Service ID: 98 - -var _ resource.Resource = &HttpResource{} -var _ resource.ResourceWithModifyPlan = &HttpResource{} -var _ resource.ResourceWithImportState = &HttpResource{} - -type HttpResource struct { - client *core.UniversalClient -} - -type HttpModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - JsonEnv types.String `tfsdk:"json_env"` - RegistryPath types.String `tfsdk:"registry_path"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewHttpResource() resource.Resource { - return &HttpResource{} -} - -func (r *HttpResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_http" -} - -func (r *HttpResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{"param": "value"}"), MarkdownDescription: "Массив переменных, будут переданы в env приложения Не изменяется после создания.", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "registry_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("nexus-sa.tst.nubes.ru/docker-nubes/jolt"), MarkdownDescription: "Путь до image, который будет установлен как deployment Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100), MarkdownDescription: "Квота ядра пода (Указывается в mili)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *HttpResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *HttpModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить json_env", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RegistryPath.IsNull() && !plan.RegistryPath.IsUnknown() && !state.RegistryPath.IsNull() && !state.RegistryPath.IsUnknown() { - if plan.RegistryPath.ValueString() != state.RegistryPath.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить registry_path", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 212: resources_core.FormatString(config.Domain), - 213: resources_core.FormatInt64(config.ResourceCPU), - 214: resources_core.FormatInt64(config.ResourceMemory), - 215: resources_core.FormatInt64(config.ResourceInstances), - 216: resources_core.FormatString(config.ResourceRealm), - 217: resources_core.FormatString(config.RegistryPath), - 241: resources_core.FormatString(config.JsonEnv), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 98, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *HttpResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 98, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 212: resources_core.FormatString(data.Domain), - 213: resources_core.FormatInt64(data.ResourceCPU), - 214: resources_core.FormatInt64(data.ResourceMemory), - 215: resources_core.FormatInt64(data.ResourceInstances), - 216: resources_core.FormatString(data.ResourceRealm), - 217: resources_core.FormatString(data.RegistryPath), - 241: resources_core.FormatString(data.JsonEnv), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 98, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 98, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HttpResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 98, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *HttpResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan HttpModel - var state HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 218: resources_core.FormatInt64(plan.ResourceCPU), - 219: resources_core.FormatInt64(plan.ResourceMemory), - 220: resources_core.FormatInt64(plan.ResourceInstances), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 98, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HttpResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *HttpResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *HttpResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/99_gitea_resource.go b/generated/dev/go/99_gitea_resource.go deleted file mode 100644 index 86e1830..0000000 --- a/generated/dev/go/99_gitea_resource.go +++ /dev/null @@ -1,493 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: gitea -// Service ID: 99 - -var _ resource.Resource = &GiteaResource{} -var _ resource.ResourceWithModifyPlan = &GiteaResource{} -var _ resource.ResourceWithImportState = &GiteaResource{} - -type GiteaResource struct { - client *core.UniversalClient -} - -type GiteaModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - PsqlUid types.String `tfsdk:"psql_uid"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewGiteaResource() resource.Resource { - return &GiteaResource{} -} - -func (r *GiteaResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_gitea" -} - -func (r *GiteaResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "psql_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *GiteaResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *GiteaModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, plan.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != plan.PsqlUid.ValueString() { - plan.PsqlUid = types.StringValue(resolvedPsqlUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - if plan.PsqlUid.ValueString() != state.PsqlUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить psql_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.PsqlUid.IsNull() || config.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.PsqlUid.IsNull() && !config.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, config.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != config.PsqlUid.ValueString() { - config.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - params := map[int]string{ - 232: resources_core.FormatInt64(config.ResourceCPU), - 233: resources_core.FormatInt64(config.ResourceMemory), - 234: resources_core.FormatInt64(config.ResourceDisk), - 235: resources_core.FormatInt64(config.ResourceInstances), - 237: resources_core.FormatString(config.Domain), - 238: resources_core.FormatString(config.PsqlUid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 99, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *GiteaResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.PsqlUid.IsNull() || data.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - if !data.PsqlUid.IsNull() && !data.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, data.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedPsqlUid != "" && resolvedPsqlUid != data.PsqlUid.ValueString() { - data.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149, 151, 153} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 99, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 232: resources_core.FormatInt64(data.ResourceCPU), - 233: resources_core.FormatInt64(data.ResourceMemory), - 234: resources_core.FormatInt64(data.ResourceDisk), - 235: resources_core.FormatInt64(data.ResourceInstances), - 237: resources_core.FormatString(data.Domain), - 238: resources_core.FormatString(data.PsqlUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 99, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 99, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 99, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.PsqlUid.IsNull() && !newState.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, newState.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != newState.PsqlUid.ValueString() { - newState.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *GiteaResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan GiteaModel - var state GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 259: resources_core.FormatInt64(plan.ResourceCPU), - 260: resources_core.FormatInt64(plan.ResourceMemory), - 261: resources_core.FormatInt64(plan.ResourceDisk), - 262: resources_core.FormatInt64(plan.ResourceInstances), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 99, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *GiteaResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *GiteaResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/dev/go/registry.go b/generated/dev/go/registry.go deleted file mode 100644 index 0a299b3..0000000 --- a/generated/dev/go/registry.go +++ /dev/null @@ -1,83 +0,0 @@ -package resources_gen - -import "github.com/hashicorp/terraform-plugin-framework/resource" - -// Code generated by tools/gen_v2. DO NOT EDIT. -func AllResources() []func() resource.Resource { - return []func() resource.Resource{ - NewAkhqResource, - NewClickhouseResource, - NewDnsrecordResource, - NewDnszoneResource, - NewDummyResource, - NewFlaskResource, - NewGiteaResource, - NewHarborResource, - NewHttpResource, - NewK8sOpenbaoResource, - NewK8sSthutrvalClusterResource, - NewK8sZitiControllerResource, - NewKafkaResource, - NewLuceeResource, - NewMariadbResource, - NewMongodbResource, - NewNextcloudResource, - NewNifiResource, - NewNodejsResource, - NewNoderedResource, - NewPgadminResource, - NewPostgresResource, - NewRabbitmqResource, - NewRedisResource, - NewS3Resource, - NewS3bucketResource, - NewSupersetResource, - NewTemplateResource, - NewValoTenantResource, - NewVappResource, - NewVcNsxtResource, - NewVcOrgResource, - NewVcVdcResource, - NewVcVdcGroupResource, - NewVcVmV3Resource, - NewVcexternalipResource, - NewZonesV2Resource, - NewClickhouseDatabaseResource, - NewClickhouseUserResource, - NewK8sOpenbaoKvResource, - NewK8sOpenbaoPolicyResource, - NewK8sOpenbaoSecretsResource, - NewKafkaTopicResource, - NewKafkaUserResource, - NewMariadbDatabaseResource, - NewMariadbUserResource, - NewMongodbUserResource, - NewPostgresDatabaseResource, - NewPostgresUserResource, - NewS3SubUserResource, - NewDummyReconcileResource, - NewDummyRedeployResource, - NewHttpRedeployResource, - NewK8sOpenbaoReconcileResource, - NewK8sOpenbaoRecoverySecretsResource, - NewK8sOpenbaoRestartResource, - NewK8sOpenbaoUpdatePolicyResource, - NewK8sOpenbaoUpdateSecretsResource, - NewK8sSthutrvalClusterReconcileResource, - NewK8sSthutrvalClusterUpdateSecretsResource, - NewLuceeRedeployResource, - NewLuceeRestartResource, - NewNextcloudRestartResource, - NewNodejsRedeployResource, - NewPgadminRedeployResource, - NewPostgresRecoveryResource, - NewPostgresRestartResource, - NewVcNsxtReconcileResource, - NewVcOrgReconcileResource, - NewVcVdcReconcileResource, - NewVcVdcGroupAddVdcResource, - NewVcVdcGroupReconcileResource, - NewVcVdcGroupRemoveVdcResource, - NewVcVmV3RedeployResource, - } -} diff --git a/generated/dev/json/.gitkeep b/generated/dev/json/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/dev/resources_yaml/.gitkeep b/generated/dev/resources_yaml/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/dev/resources_yaml/109_zones_v2.yaml b/generated/dev/resources_yaml/109_zones_v2.yaml deleted file mode 100644 index d75fa9e..0000000 --- a/generated/dev/resources_yaml/109_zones_v2.yaml +++ /dev/null @@ -1,111 +0,0 @@ -name: zones_v2 -service_id: 109 -service_display_name: Управление днс-зонами и записями -service_short_name: zonesV2 -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 254 - kind: instance - action: create - params: - - id: 761 - code: zoneName - data_type: string - required: true - regex: ^([a-z0-9-]+\.)+[a-z0-9-]+$ - maxlength: 64 - minlength: 1 - descr: Имя зоны - sort: 20 - - id: 762 - code: zoneKind - data_type: string - required: true - default: NATIVE - value_list: - - NATIVE - - SLAVE - descr: Тип зоны - sort: 30 - - id: 763 - code: zoneMastersForSlave - data_type: string - required: false - descr: Использовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов - man: Пример:
**8.8.8.8 8.8.4.4** - sort: 40 - - id: 764 - code: zoneTimeToRefresh - data_type: integer > 0 - required: true - default: "86400" - minvalue: 600 - descr: Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов - sort: 50 - - id: 765 - code: zoneTimeToRetry - data_type: integer > 0 - required: true - default: "7200" - minvalue: 600 - descr: Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов - sort: 60 - - id: 766 - code: zoneTimeToExpire - data_type: integer > 0 - required: true - default: "3600000" - minvalue: 3600 - descr: Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным - sort: 70 - - id: 767 - code: zoneTimeToLive - data_type: integer > 0 - required: true - default: "86400" - minvalue: 600 - descr: Время, в течение которого информация будет кешироваться другими DNS-серверами - sort: 80 - - id: 768 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - sort: 10 - - name: delete - id: 255 - kind: instance - action: delete - params: [] - - name: modify - id: 256 - kind: instance - action: modify - params: - - id: 769 - code: records - data_type: array-map-fixed - required: true - sort: 10 diff --git a/generated/dev/resources_yaml/110_dnszone.yaml b/generated/dev/resources_yaml/110_dnszone.yaml deleted file mode 100644 index 03d2540..0000000 --- a/generated/dev/resources_yaml/110_dnszone.yaml +++ /dev/null @@ -1,94 +0,0 @@ -name: dnszone -service_id: 110 -service_display_name: DNS зона -service_short_name: dnszone -service_man: '## ![image](https://img.icons8.com/?size=50&id=41400&format=png) Необходимо делегировать зону у регистратора на Авторитетные DNS (Сервера зон)

ns3.ngcloud.ru
``` bash
185.247.187.83
2a10:aa80:0:5::3
```

ns4.ngcloud.ru
``` bash
81.22.46.43
2a10:aa80:0:6::3
```' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 43 - kind: instance - action: create - params: - - id: 66 - code: zoneEmail - data_type: string - required: true - descr: Контактный e-mail - - id: 67 - code: zoneName - data_type: string - required: true - regex: ^([a-z0-9-]+\.)+[a-z0-9-]+$ - descr: Имя зоны - man: Имя зоны - - id: 68 - code: zoneKind - data_type: string - required: true - default: NATIVE - value_list: - - NATIVE - - SLAVE - descr: Тип зоны - - id: 69 - code: zoneMastersForSlave - data_type: string - required: false - descr: Использовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов - - id: 70 - code: zoneTimeToRefresh - data_type: string - required: true - default: "86400" - descr: Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов - - id: 71 - code: zoneTimeToRetry - data_type: string - required: true - default: "7200" - descr: Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов - - id: 72 - code: zoneTimeToExpire - data_type: string - required: true - default: "3600000" - descr: Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным - - id: 73 - code: zoneTimeToLive - data_type: string - required: true - default: "86400" - descr: Время, в течение которого информация будет кешироваться другими DNS-серверами - - id: 284 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: delete - id: 44 - kind: instance - action: delete - params: [] diff --git a/generated/dev/resources_yaml/111_dnsrecord.yaml b/generated/dev/resources_yaml/111_dnsrecord.yaml deleted file mode 100644 index 4efad14..0000000 --- a/generated/dev/resources_yaml/111_dnsrecord.yaml +++ /dev/null @@ -1,100 +0,0 @@ -name: dnsrecord -service_id: 111 -service_display_name: DNS запись -service_short_name: dnsrecord -service_man: Необходима DNS зона, в которой будет создана DNS запись.
Выберите
* Зону в которой будет создана запись
* Тип записи
* Имя записи
* Значение записи -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 45 - kind: instance - action: create - params: - - id: 75 - code: zoneUid - data_type: uuid - required: true - ref_svc_id: 110 - descr: UUID экземпляра услуги DNS-зоны - man: UUID экземпляра услуги DNS-зоны - sort: 10 - - id: 76 - code: recordType - data_type: string - required: true - value_list: - - A - - AAAA - - CNAME - - MX - - PTR - - SOA - - SRV - - TXT - - LUA - - NS - - SSHFP - descr: Тип DNS-записи - man: Тип DNS-записи - sort: 20 - - id: 77 - code: recordName - data_type: string - required: true - unique_scope: parent - descr: Имя записи. Имя зоны в конце проставляется автоматически - man: Имя записи. Имя зоны в конце проставляется автоматически - sort: 30 - - id: 78 - code: recordInput - data_type: string - required: true - descr: Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - man: Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - sort: 40 - is_modifiable: true - - id: 450 - code: recordTTL - data_type: integer > 0 - required: true - default: "3600" - maxvalue: 604800 - minvalue: 30 - descr: Time-to-Leave записи. Раз в какое время запись будет обновлена - sort: 50 - - name: delete - id: 46 - kind: instance - action: delete - params: [] - - name: modify - id: 90 - kind: instance - action: modify - params: - - id: 256 - code: recordInput - data_type: string - required: true - descr: Запись. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP diff --git a/generated/dev/resources_yaml/115_mariadb.yaml b/generated/dev/resources_yaml/115_mariadb.yaml deleted file mode 100644 index 71c47df..0000000 --- a/generated/dev/resources_yaml/115_mariadb.yaml +++ /dev/null @@ -1,318 +0,0 @@ -name: mariadb -service_id: 115 -service_display_name: Mariadb -service_short_name: mariadb -service_man: 'Mariadb кластер. Ресурсная платформа: k8s. Автоматизация: k8s operator.
Автоматическое резервное копирование, ручное восстановление.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 138 - kind: instance - action: create - params: - - id: 422 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 10 - - id: 424 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (milicores) - sort: 30 - is_modifiable: true - - id: 425 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1024" - maxvalue: 8192 - minvalue: 1024 - descr: Квота памяти пода (MBytes) - sort: 30 - is_modifiable: true - - id: 426 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 427 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 60 - is_modifiable: true - - id: 428 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к master - sort: 70 - is_modifiable: true - - id: 429 - code: ipSpaceNameMaster - data_type: string - required: false - descr: Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster - sort: 80 - is_modifiable: true - - id: 430 - code: ext_BACKUP_SCHEDULE - data_type: string - required: false - default: 0 * * * * - regex: ^(\*|(\d+|\*\/\d+|\d+(,\d+)*))\s\*\s\*\s\*\s\*$ - descr: Не обязательный. Время запуска бекапа - sort: 90 - is_modifiable: true - - id: 431 - code: appVersion - data_type: string - required: true - default: 9.4.0 - value_list: - - 8.4.0 - - 9.4.0 - descr: Версия MySQL - sort: 100 - - id: 432 - code: autoScale - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги - sort: 310 - is_modifiable: true - - id: 433 - code: autoScalePercentage - data_type: integer > 0 - required: false - default: "10" - value_list: - - "10" - - "15" - - "20" - descr: Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема - sort: 320 - is_modifiable: true - - id: 434 - code: autoScaleTechWindow - data_type: integer >= 0 - required: false - default: "0" - value_list: - - "0" - - "5" - - "12" - - "23" - descr: Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) - sort: 330 - is_modifiable: true - - id: 435 - code: autoScaleQuotaGb - data_type: integer > 0 - required: false - default: "1" - descr: Квота для autoScale - sort: 340 - is_modifiable: true - - id: 459 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - sort: 20 - - name: create_database - id: 242 - kind: subresource - action: create - subresource: database - params: - - id: 734 - code: databaseName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: 'Пример: `db01`' - - name: create_user - id: 243 - kind: subresource - action: create - subresource: user - params: - - id: 735 - code: username - data_type: string - required: true - regex: ^(?![0-9_])[a-zA-Z_][a-zA-Z0-9_]{0,62}$ - maxlength: 62 - minlength: 2 - descr: 'Пример: `myusername`' - sort: 10 - - id: 736 - code: password - data_type: string - required: true - maxlength: 62 - minlength: 10 - descr: Секрет будет записан в хранилище секретов и не будет отображаться публично - sort: 20 - is_sensitive: true - - id: 737 - code: databaseName - data_type: array-map-fixed - required: true - descr: Необходимо указать массив существующих баз - man: Если базы не существует - при выполнении операции вернётся ошибка - sort: 30 - - id: 738 - code: accessHosts - data_type: string - required: true - descr: 'Пример: `%`' - sort: 40 - - name: delete - id: 139 - kind: instance - action: delete - params: - - id: 456 - code: deleteS3Bucket - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Также удалить технический S3 Bucket с бэкапами? - sort: 10 - - name: delete_database - id: 248 - kind: subresource - action: delete - subresource: database - params: - - id: 745 - code: databaseName - data_type: string - required: true - descr: ВСЕ ДАННЫЕ ВНУТРИ БД БУДУТ УДАЛЕНЫ - - name: delete_user - id: 247 - kind: subresource - action: delete - subresource: user - params: - - id: 744 - code: username - data_type: string - required: true - descr: Имя пользователя, созданное через операцию `create_user` - - name: modify - id: 142 - kind: instance - action: modify - params: - - id: 436 - code: resourceCPU - data_type: integer > 0 - required: false - - id: 437 - code: resourceMemory - data_type: integer > 0 - required: false - - id: 438 - code: resourceInstances - data_type: integer > 0 - required: false - - id: 439 - code: resourceDisk - data_type: integer > 0 - required: false - - id: 440 - code: needExternalAddressMaster - data_type: boolean - required: false - value_list: - - "false" - - "true" - - id: 441 - code: ipSpaceNameMaster - required: false - - id: 442 - code: ext_BACKUP_SCHEDULE - data_type: string - required: false - - id: 443 - code: autoScale - data_type: boolean - required: false - value_list: - - "false" - - "true" - - id: 444 - code: autoScalePercentage - data_type: integer > 0 - required: false - - id: 445 - code: autoScaleTechWindow - data_type: integer >= 0 - required: false - - id: 446 - code: autoScaleQuotaGb - data_type: integer > 0 - required: false - - name: resume - id: 141 - kind: instance - action: resume - params: [] - - name: suspend - id: 140 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/116_kafka.yaml b/generated/dev/resources_yaml/116_kafka.yaml deleted file mode 100644 index b0b9c6d..0000000 --- a/generated/dev/resources_yaml/116_kafka.yaml +++ /dev/null @@ -1,291 +0,0 @@ -name: kafka -service_id: 116 -service_display_name: ApacheKafka -service_short_name: kafka -service_man: '# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Идентификатор организации
Уникальный идентификатор созданной организации. Используется для всех дальнейших API-операций.

### Статус организации
Отражает текущее состояние: active, suspended, modifying, deleting.

### Параметры сети
Выходные данные при наличии ipSpaces: список выделенных внешних IP, имя ip_space, количество IP.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)**;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к этой организации.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak.

' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 148 - kind: instance - action: create - params: - - id: 461 - code: resourceInstances - data_type: integer > 0 - required: true - value_list: - - "1" - - "2" - - "3" - - "4" - - "5" - minvalue: 1 - descr: 'Пример: `2`' - sort: 20 - is_modifiable: true - - id: 462 - code: resourceMemory - data_type: integer > 0 - required: true - minvalue: 1000 - descr: 'Пример: `2048`' - sort: 30 - is_modifiable: true - - id: 463 - code: resourceCPU - data_type: integer > 0 - required: true - minvalue: 1000 - descr: 'Пример: `2000`' - sort: 40 - is_modifiable: true - - id: 464 - code: resourceDisk - data_type: integer > 0 - required: true - descr: 'Пример: `20`' - sort: 50 - is_modifiable: true - - id: 465 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`' - sort: 60 - is_modifiable: true - - id: 466 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - sort: 70 - is_modifiable: true - - id: 469 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 5 - - name: create_topic - id: 165 - kind: subresource - action: create - subresource: topic - man: '# Инструкция по управлению топиками Apache Kafka через платформу

## 1. Общая информация

---

Топик — это основная сущность в Apache Kafka, предназначенная для приёма сообщений от продюсеров и передачи их консюмерам.
Платформа позволяет создавать, удалять и изменять параметры топиков без прямого доступа к брокерам, обеспечивая удобное управление через интерфейс или API.

---

## Доступные операции

- **create_topic** — Создание топика
- **modify_topic** — Модификация топика
- **delete_topic** — Удаление топика

---

## 2. Параметры создания топика

Ниже перечислены параметры, которые необходимо указать при создании нового топика:

* **Имя топика**
Название топика.
Должно быть уникальным в пределах кластера.
Пример: `orders-events`.

* **Партиции**
Количество партиций топика.
Рекомендуется выбирать с учётом уровня параллелизма потребителей и предполагаемой нагрузки.
Пример: `6`. Здесь важно рассказать о том как происходит расчет оптимального количества
Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.

* **Реплики**
Количество реплик для каждой партиции.
Обычно равно количеству доступных брокеров или меньше.
Пример: `3`.


---

## 4. Параметры модификации топика

Для уже существующих топиков можно изменять параметры. Все параметры являются опциональными:

* **Имя топика**
Название топика.
Пример: `orders-events`.

* **Партиции**
Новое количество партиций.
Пример: `12`.

* **Реплики**
Новое количество реплик.
Пример: `2`.

---

## 5. Рекомендации

* Планируйте количество партиций с запасом — уменьшение их числа невозможно.
* Количество реплик должно соответствовать требуемому уровню отказоустойчивости, но не превышать количество брокеров.
* Изменение параметров топика в рабочем окружении может временно влиять на производительность. Рекомендуется проводить крупные изменения в периоды минимальной нагрузки.

---' - params: - - id: 523 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`' - sort: 10 - - id: 524 - code: partitions - data_type: integer > 0 - required: true - descr: Число партиций можно увеличить, но уменьшить их нельзя. - - id: 525 - code: replicas - data_type: integer > 0 - required: true - descr: Количество реплик не может привышать количество реплик брокера - sort: 20 - - name: create_user - id: 168 - kind: subresource - action: create - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 530 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - - id: 531 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`' - - id: 532 - code: operations - data_type: string - required: true - descr: 'Пример: `Create, Describe, Read, Write`' - - id: 533 - code: group - data_type: string - required: true - descr: 'Пример: `order-consumers` или `*`' - - id: 534 - code: accessHosts - data_type: string - required: true - descr: 'Пример: `192.168.1.0/24` или `*`' - - name: delete - id: 149 - kind: instance - action: delete - params: [] - - name: delete_topic - id: 167 - kind: subresource - action: delete - subresource: topic - params: - - id: 529 - code: nameTopic - data_type: string - required: true - descr: Необходимо выбрать топик, который необходимо удалить - - name: delete_user - id: 170 - kind: subresource - action: delete - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 540 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - - name: modify - id: 162 - kind: instance - action: modify - params: - - id: 501 - code: resourceInstances - data_type: integer > 0 - required: false - value_list: - - "1" - - "2" - - "3" - - "4" - - "5" - descr: 'Пример: `2`' - - id: 502 - code: resourceMemory - data_type: integer > 0 - required: false - minvalue: 1000 - descr: 'Пример: `2048`' - - id: 503 - code: resourceCPU - required: false - minvalue: 1000 - descr: 'Пример: `2000`' - - id: 504 - code: resourceDisk - data_type: integer > 0 - required: false - descr: 'Пример: `20`' - - id: 505 - code: needExternalAddressMaster - data_type: boolean - required: false - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`' - - id: 506 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - - name: modify_topic - id: 166 - kind: subresource - action: modify - subresource: topic - man: '# Инструкция по управлению топиками Apache Kafka через платформу

## 1. Общая информация

---

Топик — это основная сущность в Apache Kafka, предназначенная для приёма сообщений от продюсеров и передачи их консюмерам.
Платформа позволяет создавать, удалять и изменять параметры топиков без прямого доступа к брокерам, обеспечивая удобное управление через интерфейс или API.

---

## Доступные операции

- **create_topic** — Создание топика
- **modify_topic** — Модификация топика
- **delete_topic** — Удаление топика

---

## 2. Параметры создания топика

Ниже перечислены параметры, которые необходимо указать при создании нового топика:

* **Имя топика**
Название топика.
Должно быть уникальным в пределах кластера.
Пример: `orders-events`.

* **Партиции**
Количество партиций топика.
Рекомендуется выбирать с учётом уровня параллелизма потребителей и предполагаемой нагрузки.
Пример: `6`. Здесь важно рассказать о том как происходит расчет оптимального количества
Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.

* **Реплики**
Количество реплик для каждой партиции.
Обычно равно количеству доступных брокеров или меньше.
Пример: `3`.


---

## 4. Параметры модификации топика

Для уже существующих топиков можно изменять параметры. Все параметры являются опциональными:

* **Имя топика**
Название топика.
Пример: `orders-events`.

* **Партиции**
Новое количество партиций.
Пример: `12`.

* **Реплики**
Новое количество реплик.
Пример: `2`.

---

## 5. Рекомендации

* Планируйте количество партиций с запасом — уменьшение их числа невозможно.
* Количество реплик должно соответствовать требуемому уровню отказоустойчивости, но не превышать количество брокеров.
* Изменение параметров топика в рабочем окружении может временно влиять на производительность. Рекомендуется проводить крупные изменения в периоды минимальной нагрузки.

---' - params: - - id: 526 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`' - sort: 10 - - id: 527 - code: partitions - required: false - descr: Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - sort: 30 - - id: 528 - code: replicas - required: false - descr: Количество партиций ≤ (число брокеров). Пример `2` - sort: 20 - - name: modify_user - id: 169 - kind: subresource - action: modify - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 535 - code: nameTopic - data_type: string - required: false - descr: 'Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`' - - id: 536 - code: operations - data_type: string - required: false - descr: 'Пример: `Create, Describe, Read, Write`' - - id: 537 - code: group - data_type: string - required: false - descr: 'Пример: `order-consumers` или `*`' - - id: 538 - code: accessHosts - data_type: string - required: false - descr: 'Пример: `192.168.1.0/24` или `*`' - - id: 539 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - sort: 10 - - name: resume - id: 161 - kind: instance - action: resume - params: [] - - name: suspend - id: 160 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/119_akhq.yaml b/generated/dev/resources_yaml/119_akhq.yaml deleted file mode 100644 index 7339976..0000000 --- a/generated/dev/resources_yaml/119_akhq.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: akhq -service_id: 119 -service_display_name: Akhq -service_short_name: Akhq -service_man: '# Инструкция по развертыванию Apache Kafka через платформу

---
## 1. Общая информация
AKHQ — это веб-интерфейс для работы с кластерами Apache Kafka.
Позволяет просматривать топики, consumer group''ы, сообщения, ACL, схему безопасности, состояние брокеров и метаданные.
Поддерживает работу с несколькими кластерами Kafka одновременно, включая внутренние и внешние (TLS) подключения.

## Доступные операции
- **create** — Создание ресурса AKHQ
- **suspend** — Остановка ресурса
- **resume** — Возобновление работы ресурса
- **modify** — Модификация настроек
- **delete** — Удаление ресурса

---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса Kafka:

* **Кластер Kafka к которому нужно настроить подключение**
Для использования AKHQ необходимо предварительно развернуть сервис Kafka. Пример: `kafka-external`.

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество узлов для работы Akhq. Пример `2`

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `512`

* **Квота (millicore ) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `500`

* **Имя домена:**
Dns Имя по которому будет происходить обращение к сервису. Указать необходимо уникальное имя до . ( то есть если необходимо получить dns ui) Пример: `kafka-external`

---
## 4. Выходные параметры
После успешного развертывания ресурса Kafka платформа возвращает ряд параметров.
Ключевым из них является:

**connectionUrl**
Это полное доменное имя (FQDN), по которому будет доступен интерфейс AKHQ. После развёртывания подождите несколько минут — UI станет доступен по HTTPS, как только все сервисы полностью запустятся.

**Учетные данные**
Здесь представлены поля для ввода логина и пароля, с помощью которых вы сможете авторизоваться в сервисе.

---
## 5. Дополнительная информация
Учётные записи, созданные для работы с AKHQ, предоставляют доступ только для просмотра данных. Для управления Kafka, пожалуйста, используйте возможности личного кабинета.
---' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 175 - kind: instance - action: create - params: - - id: 550 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 551 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - minvalue: 512 - descr: 'Пример: `1024`' - sort: 20 - - id: 552 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - minvalue: 500 - descr: 'Пример: `1000`' - sort: 30 - - id: 553 - code: domain - data_type: string - required: true - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 40 - - id: 554 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - minvalue: 1 - sort: 11 - - id: 555 - code: kafkaUid - data_type: uuid - required: true - ref_svc_id: 116 - descr: Выбрать кластер из списка - sort: 5 - is_modifiable: true - - name: delete - id: 176 - kind: instance - action: delete - params: [] - - name: modify - id: 180 - kind: instance - action: modify - params: - - id: 565 - code: kafkaUid - data_type: uuid - required: true - ref_svc_id: 116 - descr: Выбрать кластер из списка - - name: resume - id: 178 - kind: instance - action: resume - params: [] - - name: suspend - id: 177 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/120_clickhouse.yaml b/generated/dev/resources_yaml/120_clickhouse.yaml deleted file mode 100644 index efae3cf..0000000 --- a/generated/dev/resources_yaml/120_clickhouse.yaml +++ /dev/null @@ -1,417 +0,0 @@ -name: clickhouse -service_id: 120 -service_display_name: ClickHouse -service_short_name: clickhouse -service_man: '# Инструкция по управлению кластерами и пользователями ClickHouse

---

## Общая информация

ClickHouse — это колоночная система управления базами данных, предназначенная для обработки аналитических запросов в реальном времени. Платформа позволяет создавать, удалять, приостанавливать и возобновлять кластеры ClickHouse, а также управлять базами данных и пользователями.

Кластер создаётся через оператор Altinity (`https://github.com/Altinity/clickhouse-operator`) в ресурсной платформе типа `k8s`

Кластеры могут создаваться шардированными с произвольным количеством реплик. Для обеспечения отказоустойчивости и координации обязательно включение параметра `Создать ClickHouse-Keeper`.

Кластера создаются с обязательным бекапом. Для этого необходимо предварительно создать услугу `S3 Object Storage`.
---

## Доступные операции

* **create** — Создание кластера
* **delete** — Удаление кластера
* **suspend** — Приостановка работы кластера
* **resume** — Возобновление работы кластера
* **create_database** — Создание базы данных
* **delete_database** — Удаление базы данных
* **create_user** — Создание пользователя и настройка прав доступа к базе данных
* **delete_user** — Удаление пользователя

## Процесс создания и первого подключения

1. Выполнить операцию `create` - будет создан кластер
2. Выполнить операцию `create_database` - будет создана база данных
3. Выполнить операцию `create_user` - будет создан пользователь (выбрать доступ подключения к БД, созданной в п.2)

## Примеры подключения

### Подключение через HTTP-интерфейс

```bash
# Проверка доступности кластера
curl "http://<username>:<password>@<host>:8123/" -d "SELECT 1"

# Выполнение запроса
curl "http://<username>:<password>@<host>:8123/" -d "SHOW DATABASES"
```

## Простые кейсы
*Создать БД и обычной таблицы*
```clickhouse
CREATE TABLE database.table
(
id UInt64,
value String
)
ENGINE = MergeTree()
ORDER BY id;

INSERT INTO database.table SELECT number, toString(number) FROM numbers(10000000);

SELECT count() FROM database.table;
```
Базы и таблицы не реплицируются без специального ключа (`ON CLUSTER ''clickhousek8s''`)
В случае создания в стиле, описанным выше, необходимо будет выполнять действия на всех шардах/репликах


*Создание БД и шардированной таблицы*
```clickhouse
CREATE TABLE database.localUsers
(
id UInt64,
value String
)
ENGINE = MergeTree()
ORDER BY id;

CREATE TABLE database.shardedTable
AS localUsers
ENGINE = Distributed(''clickhousek8s'', ''database'', ''localUsers'', id);

INSERT INTO shardedTable SELECT number, toString(number) FROM numbers(10000000);

SELECT count() FROM shardedTable;
```
Важный момент - в данном примере таблицы придётся также выполнять на всех нодах ClickHouse

*Создание реплицируемой и шардированной таблицы*
```clickhouse
CREATE TABLE IF NOT EXISTS database.localUsers ON cluster ''clickhousek8s''
(
user_id UInt64,
name String,
email String
)
ENGINE = ReplicatedMergeTree(
''/clickhouse/tables/{shard}/localUsers'',
''{replica}''
)
ORDER BY user_id;

CREATE TABLE IF NOT EXISTS database.users ON cluster ''clickhousek8s''
AS database.localUsers
ENGINE = Distributed(''clickhousek8s'', ''database'', ''localUsers'', rand());

INSERT INTO database.users VALUES (1, ''Alice'', ''alice@example.com'');
INSERT INTO database.users VALUES (2, ''Bob'', ''bob@example.com'');
INSERT INTO database.users VALUES (3, ''Charlie'', ''charlie@example.com'');
INSERT INTO database.users VALUES (4, ''David'', ''david@example.com'');
INSERT INTO database.users VALUES (5, ''Gosha'', ''gosha@example.com'');
INSERT INTO database.users VALUES (6, ''Eve'', ''eve@example.com'');
INSERT INTO database.users VALUES (7, ''Frank'', ''frank@example.com'');
INSERT INTO database.users VALUES (8, ''Grace'', ''grace@example.com'');
INSERT INTO database.users VALUES (9, ''Hannah'', ''hannah@example.com'');
INSERT INTO database.users VALUES (10, ''Ivan'', ''ivan@example.com'');

SELECT * FROM database.localUsers;
SELECT * FROM database.users;

SELECT COUNT(*) AS total_users FROM database.users;
SELECT COUNT(*) AS total_users_local FROM database.localUsers;
```' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 181 - kind: instance - action: create - man: Операция создания кластера ClickHouse

Для подключения к кластеру также необходимо создать базу данных через операцию `create_database` и создание пользователя через операцию `create_user` - params: - - id: 572 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Кластер Kubernetes в котором будет развёрнуто приложение - man: Выбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы - sort: 10 - - id: 573 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - man: '**Если список не отображается**
перейдите в раздел `S3 Object Storage`
операция `create`' - sort: 20 - - id: 574 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `3`' - man: '**Для синхронизации данных между репликами** необходимо включить `Создать ClickHouse-Keeper`' - sort: 30 - is_modifiable: true - - id: 575 - code: resourceInstancesShards - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - man: '**Шард** - это часть данных, разделенная на разные узлы (серверы) для горизонтального масштабирования и обработки больших объемов информации.
**Реплика** - это точная копия данных внутри одного шарда' - sort: 40 - is_modifiable: true - - id: 576 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 8000 - minvalue: 1000 - descr: 'Пример: `1000`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 50 - is_modifiable: true - - id: 577 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1536" - maxvalue: 8192 - minvalue: 1536 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 60 - is_modifiable: true - - id: 578 - code: appVersion - data_type: string - required: true - default: "25.10" - value_list: - - "25.10" - descr: Версия `clickhouse-server` - sort: 70 - is_modifiable: true - - id: 579 - code: resourceDisk - data_type: integer > 0 - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `100`' - man: Указывается в Gigabytes - sort: 80 - is_modifiable: true - - id: 580 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Позволяет подключиться извне к ClickHouse - man: Для выделения IP также необходимо указать имя Ip-space.
Его можно получить из свойств ресурсной платформы - sort: 90 - is_modifiable: true - - id: 581 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - man: Имя ipSpace для публикации внешнего адреса

Не может быть пустым, если включен `Выделение белого ip для master ноды` - sort: 100 - is_modifiable: true - - id: 582 - code: needCreateKeeper - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Необходим для кластеризации ClickHouse - man: Аналог `Zookeeper`, представленный от ClickHouse - sort: 200 - is_modifiable: true - - id: 583 - code: resourceCPUKeeper - data_type: integer > 0 - required: true - default: "50" - maxvalue: 8000 - minvalue: 50 - descr: 'Пример: `100`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 210 - is_modifiable: true - - id: 584 - code: resourceMemoryKeeper - data_type: integer > 0 - required: true - default: "152" - maxvalue: 8192 - minvalue: 152 - descr: 'Пример: `256`' - man: Указывается в Megabytes - sort: 220 - is_modifiable: true - - id: 585 - code: resourceInstancesKeeper - data_type: integer > 0 - required: true - default: "1" - value_list: - - "1" - - "3" - maxvalue: 3 - minvalue: 1 - descr: 'Пример: `1`' - man: Для **теста** - 1 нода.
Для **продуктива** - 3 ноды - sort: 230 - is_modifiable: true - - id: 586 - code: ext_BACKUP_SCHEDULE - data_type: string - required: true - default: 0 0 * * * - regex: ^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$ - descr: Принимает формат `CRON` - sort: 500 - is_modifiable: true - - id: 587 - code: ext_BACKUP_NUM_TO_RETAIN - data_type: integer > 0 - required: true - default: "7" - maxvalue: 60 - minvalue: 3 - descr: 'Пример: `7`' - man: Кол-во **полных** резервных копий
Кол-во инкрементов - неограничено

Полная резервная копия выполняется раз в неделю
*Если изначально полной резервной копии нет* выполняется полный бекап
В остальные дни по крону выполняются **инкременты** - sort: 510 - is_modifiable: true - - name: create_database - id: 186 - kind: subresource - action: create - subresource: database - man: База данных создаётся на всех репликах кластера ClickHouse - params: - - id: 600 - code: databaseName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: 'Пример: `db01`' - sort: 10 - - name: create_user - id: 185 - kind: subresource - action: create - subresource: user - params: - - id: 596 - code: username - data_type: string - required: true - regex: ^(?![0-9_])[a-zA-Z_][a-zA-Z0-9_]{0,62}$ - maxlength: 62 - minlength: 2 - descr: 'Пример: `myusername`' - sort: 10 - - id: 598 - code: databaseName - data_type: json - required: true - default: '["database"]' - descr: Необходимо указать массив существующих баз - man: Если базы не существует - при выполнении операции вернётся ошибка - sort: 30 - - id: 599 - code: accessHosts - data_type: string - required: true - default: ::/0 - descr: 'Пример: `::/0`' - sort: 40 - - name: delete - id: 184 - kind: instance - action: delete - man: Удаление возможно только после остановки сервиса через операцию `suspend`
После выполнения операции необходимо выждать определенное кол-во времени - params: [] - - name: delete_database - id: 188 - kind: subresource - action: delete - subresource: database - man: Необратимое действие!!!
Трижды подумай, заблокируй телефон тимлида и не выполняй это действие - params: - - id: 602 - code: databaseName - data_type: string - required: true - descr: ВСЕ ДАННЫЕ ВНУТРИ БД БУДУТ УДАЛЕНЫ - - name: delete_user - id: 187 - kind: subresource - action: delete - subresource: user - params: - - id: 601 - code: username - required: true - descr: Имя пользователя, созданное через операцию `create_user` - - name: modify - id: 189 - kind: instance - action: modify - params: - - id: 603 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `3`' - man: '**Для синхронизации данных между репликами** необходимо включить `Создать ClickHouse-Keeper`' - sort: 10 - - id: 604 - code: resourceInstancesShards - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - man: '**Шард** - это часть данных, разделенная на разные узлы (серверы) для горизонтального масштабирования и обработки больших объемов информации.
**Реплика** - это точная копия данных внутри одного шарда' - sort: 20 - - id: 605 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 8000 - minvalue: 1000 - descr: 'Пример: `1000`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 30 - - id: 606 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 1536 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 40 - - id: 607 - code: appVersion - data_type: string - required: true - default: "25.10" - descr: Версия `clickhouse-server` - sort: 50 - - id: 608 - code: resourceDisk - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `100`' - man: Указывается в Gigabytes
**Нельзя** выставлять меньше текущего значения - sort: 60 - - id: 609 - code: needExternalAddressMaster - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Позволяет подключиться извне к ClickHouse - man: Для выделения IP также необходимо указать имя Ip-space.
Его можно получить из свойств ресурсной платформы - sort: 70 - - id: 610 - code: ipSpaceNameMaster - data_type: string - required: true - descr: 'Пример: `internet-no-antiddos-v1`' - man: Имя ipSpace для публикации внешнего адреса

Не может быть пустым, если включен `Выделение белого ip для master ноды` - sort: 80 - - id: 611 - code: needCreateKeeper - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Необходим для кластеризации ClickHouse - man: Аналог `Zookeeper`, представленный от ClickHouse - sort: 200 - - id: 612 - code: resourceCPUKeeper - data_type: integer > 0 - required: true - maxvalue: 8000 - minvalue: 50 - descr: 'Пример: `100`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 210 - - id: 613 - code: resourceMemoryKeeper - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 152 - descr: 'Пример: `256`' - man: Указывается в Megabytes - sort: 220 - - id: 614 - code: resourceInstancesKeeper - data_type: integer > 0 - required: true - value_list: - - "1" - - "3" - maxvalue: 3 - minvalue: 1 - descr: 'Пример: `1`' - man: Для **теста** - 1 нода.
Для **продуктива** - 3 ноды - sort: 230 - - id: 615 - code: ext_BACKUP_SCHEDULE - data_type: string - required: true - default: 0 0 * * * - regex: ^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$ - descr: Принимает формат `CRON` - sort: 500 - - id: 616 - code: ext_BACKUP_NUM_TO_RETAIN - data_type: integer > 0 - required: true - maxvalue: 60 - minvalue: 3 - descr: 'Пример: `7`' - man: Кол-во **полных** резервных копий
Кол-во инкрементов - неограничено

Полная резервная копия выполняется раз в неделю
*Если изначально полной резервной копии нет* выполняется полный бекап
В остальные дни по крону выполняются **инкременты** - sort: 510 - - name: resume - id: 183 - kind: instance - action: resume - params: [] - - name: suspend - id: 182 - kind: instance - action: suspend - man: Операция приводит к удалению всех подов
Persistent Volume остаются нетронутыми - params: [] diff --git a/generated/dev/resources_yaml/12_s3.yaml b/generated/dev/resources_yaml/12_s3.yaml deleted file mode 100644 index 1bcb6be..0000000 --- a/generated/dev/resources_yaml/12_s3.yaml +++ /dev/null @@ -1,121 +0,0 @@ -name: s3 -service_id: 12 -service_display_name: S3 Object Storage -service_short_name: s3 -service_man: Руководство доступно по ссылке:
https://docs.s3.msk-1.ngcloud.ru/s3/s3.description.html -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 1 - kind: instance - action: create - params: - - id: 163 - code: resourceRealm - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: кластер S3 для подключения - sort: 20 - - id: 320 - code: displayName - data_type: string - required: true - descr: Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента - sort: 10 - - name: create_sub_user - id: 6 - kind: subresource - action: create - subresource: sub_user - params: - - id: 60 - code: subUserName - data_type: string - required: true - - id: 61 - code: subUserAccess - data_type: string - required: true - value_list: - - read - - write - - readwrite - - full - - name: delete - id: 5 - kind: instance - action: delete - params: [] - - name: delete_sub_user - id: 7 - kind: subresource - action: delete - subresource: sub_user - params: - - id: 63 - code: subUserName - data_type: string - required: true - descr: subUserName. По идее услуга уже создана - должен передаваться из ЛК - - name: modify - id: 4 - kind: instance - action: modify - man: При первичном вызове операции услуга Trial прекращает действие - params: - - id: 50 - code: maxSizeGbPerUser - data_type: integer > 0 - required: false - maxvalue: 50000 - minvalue: 1 - descr: maxSizeGb. Передаём руками - man: maxSizeGb. Передаём руками - - id: 51 - code: maxObjectsPerBucket - data_type: integer > 0 - required: false - maxvalue: 1e+07 - minvalue: 1 - descr: Квота на бакет. Кол-во объектов. Передаём руками - man: Квота на бакет. Кол-во объектов. Передаём руками - - id: 52 - code: maxBucketsPerUser - data_type: integer > 0 - required: false - maxvalue: 1000 - minvalue: 1 - descr: Квота на пользователя. Количество бакетов пользователя. Передаём руками - man: Квота на пользователя. Количество бакетов пользователя. Передаём руками - - name: resume - id: 3 - kind: instance - action: resume - params: [] - - name: suspend - id: 2 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/13_s3bucket.yaml b/generated/dev/resources_yaml/13_s3bucket.yaml deleted file mode 100644 index 68e506c..0000000 --- a/generated/dev/resources_yaml/13_s3bucket.yaml +++ /dev/null @@ -1,90 +0,0 @@ -name: s3bucket -service_id: 13 -service_display_name: S3 бакет -service_short_name: s3bucket -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 51 - kind: instance - action: create - params: - - id: 124 - code: s3UserUid - data_type: uuid - required: true - ref_svc_id: 12 - descr: UID Корневой услуги S3. На основе него будет создан бакет. - - id: 125 - code: bucketName - data_type: string - required: true - descr: Имя бакета s3 - - id: 126 - code: maxSize - required: true - default: "-1" - descr: Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes - man: Максимальный размер бакета s3. Если поставить 0, будет безлимит. Размер указывается в Bytes - - id: 127 - code: readAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. - - id: 128 - code: listAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. - - id: 129 - code: corsAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS - - id: 130 - code: placement - data_type: string - required: true - default: HOT - value_list: - - HOT - - COLD - descr: Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения - - name: delete - id: 52 - kind: instance - action: delete - params: [] diff --git a/generated/dev/resources_yaml/149_valo_tenant.yaml b/generated/dev/resources_yaml/149_valo_tenant.yaml deleted file mode 100644 index ddb0afb..0000000 --- a/generated/dev/resources_yaml/149_valo_tenant.yaml +++ /dev/null @@ -1,98 +0,0 @@ -name: valo_tenant -service_id: 149 -service_display_name: VALO Cloud -service_short_name: valoTenant -service_man: '# Инструкция по развертыванию Тенант Valo через платформу

## 1. Общая информация
Тенант Valo — логический изолированный экземпляр сервиса VALO Cloud, предоставляющий защищённое облачное хранилище, синхронизацию данных и доступ к документам с различных устройств. При создании тенант автоматически разворачивается в тестовом режиме сроком на 2 месяца. Перевод в промышленную эксплуатацию выполняется отдельной операцией.

### Доступные операции

* **create** — создание нового тенанта в тестовом режиме сроком на 2 месяца.
* **modify** — изменение настроек тенанта, включая перевод из ТЕСТ в ПРОД.
* **suspend** — выключение (приостановка работы) тенанта.
* **resume** — включение ранее приостановленного тенанта.
* **delete** — удаление тенанта; доступно только после выполнения операции suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создан тенант.
Пример значения: `valo.ngcloud.ru`.

### DNS-Префикс
Описание: Будет добавлено в зону valo.ngcloud.ru
Пример значения: `mysimpledomain`.

### Параметры хранилища
Описание: Сколько места будет выделено под использование в тенанте. Данные хранятся в S3. Размер указывается в Gigabytes
Пример значения: `10`.

### Настройки тенанта
Описание: Ряд конфигурации Valo-тенанта, такие как настройки пользователя и доступного функционала
Пример значения: `опционально в рамках настройки`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
Достаточно развернуть тенант в ТЕСТ. Срок предоставляется в 2 месяца. По истечению срока тенант автоматически переводится в `suspend` на стороне ресурсной платформы

### Промышленное окружение
Для разблокировки используйте операцию `modify`

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Статус тенанта
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация
Тенант всегда создаётся в режиме ТЕСТ и не может быть сразу переведён в ПРОД без операции modify.
Удаление тенанта возможно только после его выключения с помощью операции suspend.
Срок тестового режима составляет 2 месяца с момента создания.
Операции suspend и resume используются для временного управления доступностью сервиса без потери конфигурации.
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 202 - kind: instance - action: create - params: - - id: 655 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - sort: 10 - - id: 656 - code: domain - data_type: string - required: true - regex: ^[a-z0-9](?:[a-z0-9-]{3,61}[a-z0-9])?$ - maxlength: 61 - minlength: 3 - descr: Будет добавлено в зону valo.ngcloud.ru - sort: 20 - - id: 657 - code: valoOptions - data_type: map-fixed - required: true - default: '{}' - sort: 40 - is_modifiable: true - - id: 658 - code: s3Storage - data_type: integer > 0 - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: Параметр указывается в `Gb` - man: Данные хранятся в отдельном экземпляре S3 - sort: 30 - is_modifiable: true - - name: delete - id: 206 - kind: instance - action: delete - params: [] - - name: modify - id: 203 - kind: instance - action: modify - params: - - id: 659 - code: valoOptions - data_type: map-fixed - required: true - sort: 10 - - id: 660 - code: s3Storage - data_type: integer > 0 - required: true - descr: Параметр указывается в `Gb` - man: Данные хранятся в отдельном экземпляре S3 - sort: 20 - - name: resume - id: 205 - kind: instance - action: resume - params: [] - - name: suspend - id: 204 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/150_k8s_sthutrval_cluster.yaml b/generated/dev/resources_yaml/150_k8s_sthutrval_cluster.yaml deleted file mode 100644 index 4026df2..0000000 --- a/generated/dev/resources_yaml/150_k8s_sthutrval_cluster.yaml +++ /dev/null @@ -1,114 +0,0 @@ -name: k8s_sthutrval_cluster -service_id: 150 -service_display_name: Kubernetes кластер Штурвал -service_short_name: k8sSthutrvalCluster -service_man: Перед разворачиванием убедиться, что в облаке есть 2 свободных невыделенных IP в пуле -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 108 - kind: instance - action: create - params: - - id: 750 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 751 - code: controlPlaneConfiguration - data_type: map-fixed - required: true - sort: 30 - is_modifiable: true - - id: 752 - code: workerConfiguration - data_type: array-map-fixed - required: true - default: '[{}]' - sort: 40 - is_modifiable: true - - id: 753 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 50 - is_modifiable: true - - id: 755 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - name: delete - id: 109 - kind: instance - action: delete - params: [] - - name: modify - id: 110 - kind: instance - action: modify - man: При изменении кол-ва узлов, удаления группы, если в этой группе есть поды на которых есть PV с named-дисками, удаляться ноды сами НЕ БУДУТ.
Убедитесь, что они будут смигрированы на другие ноды в процессе прежде чем группа узлов/узлы будут удалены - params: - - id: 756 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 757 - code: controlPlaneConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 758 - code: workerConfiguration - data_type: array-map-fixed - required: true - sort: 30 - - id: 759 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 40 - - name: reconcile - id: 253 - kind: action - action: reconcile - params: [] - - name: resume - id: 174 - kind: instance - action: resume - params: [] - - name: suspend - id: 173 - kind: instance - action: suspend - params: [] - - name: update_secrets - id: 179 - kind: action - action: update_secrets - params: [] diff --git a/generated/dev/resources_yaml/151_k8s_openbao.yaml b/generated/dev/resources_yaml/151_k8s_openbao.yaml deleted file mode 100644 index 62c05ed..0000000 --- a/generated/dev/resources_yaml/151_k8s_openbao.yaml +++ /dev/null @@ -1,351 +0,0 @@ -name: k8s_openbao -service_id: 151 -service_display_name: Vault -service_short_name: k8sOpenbao -service_man: '# Инструкция по развертыванию Хранилища секретов через платформу

## 1. Общая информация
Хранилище секретов — сервис централизованного и защищённого хранения чувствительных данных (секретов, ключей, конфигураций). Предназначен для использования приложениями и сервисами в Kubernetes с управлением доступом на основе ролей.
В качестве приложения используется открытый проект OpenBao с поддержкой кластерного режима RAFT.

### Доступные операции
**create** — Создание хранилища секретов и инициализация кластера.
**delete** — Удаление хранилища секретов с полной очисткой всех связанных сущностей.
**modify** — Изменение параметров развернутого хранилища секретов.
**suspend** — Приостановка работы кластера без удаления Persistent Volume.
**resume** — Возобновление работы кластера с автоматическим unseal всех нод.
**restart** — Поочередный перезапуск нод с последующим подключением в кластер.
**create_kv** — Создание Key/Value хранилища версии V2.
**delete_kv** — Удаление Key/Value хранилища со всеми содержащимися секретами.
**create_secrets** — Создание секрета внутри Key/Value хранилища.
**delete_secrets** — Удаление секрета из Key/Value хранилища.
**update_secrets** — Обновление значения секрета.
**recovery_secrets** — Откат секрета к указанной версии.
**create_role** — Создание роли для управления Key/Value хранилищем или секретами.
**update_role** — Обновление параметров роли.
**delete_role** — Удаление роли доступа.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: Кластер Kubernetes, в котором будет развернуто приложение.
Формат значения: имя Kubernetes-кластера.

### Имя домена
Описание: Доменное имя сервиса. При указании полного FQDN выполняется проверка DNS A-записи или добавляется А-запись в техническую зону.
Формат значения: secrets.domain.com / mysecretdomain.

### Кол-во реплик
Описание: Количество узлов в кластере.
Формат значения: целое число.

### Квота ядра пода
Описание: Лимит CPU для одного узла. Указывается в milicores (1000 milicores = 1 CPU).
Формат значения: целое число.

### Квота памяти пода
Описание: Лимит оперативной памяти для одного узла. Указывается в megabytes.
Формат значения: целое число.

### Размер диска под хранение секретов
Описание: Объем диска для хранения данных. Фактический объем равен значению, умноженному на количество реплик. Указывается в Gigabytes
Формат значения: целое число.

### Версия OpenBao
Описание: Версия OpenBao для развертывания сервиса.
Формат значения: выбор из предоставленного списка версий.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
Кол-во реплик: 2.
Квота ядра пода: 200.
Квота памяти пода: 256.
Размер диска под хранение секретов: 1.
Версия OpenBao: актуальная стабильная версия.

### Промышленное окружение
Кол-во реплик: от 3.
Квота ядра пода: от 1000.
Квота памяти пода: от 1024.
Размер диска под хранение секретов: от 10.
Версия OpenBao: актуальная стабильная версия.

---

## 4. Выходные параметры
Настройки внутри хранилища (kv/secrets/roles) — конфигурации Key/Value, секретов и ролей, созданные соответствующими операциями.
Настройки самого хранилище (сайзинг, объемы) — параметры ресурсов и хранилища данных, примененные к сервису.
Статус кластера (running / suspended) — текущее состояние работы кластера.
url для подключения к веб — адрес веб-интерфейса сервиса.

---

## 5. Дополнительная информация
При удалении хранилища все данные и настройки безвозвратно удаляются.
При использовании доменного имени требуется корректная настройка DNS.
Операции управления секретами и ролями выполняются только после успешного создания хранилища.
Удаление кластера производится через операцию `suspend`, а удаление становится доступно через 14 дней после остановки кластера
Правило выше не относится к операции `delete_kv` / `delete_secrets` / `delete_role`' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 210 - kind: instance - action: create - params: - - id: 663 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Кластер Kubernetes в котором будет развёрнуто приложение - man: Выбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы - sort: 0 - - id: 664 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 8000 - minvalue: 250 - descr: 'Пример: `500`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 30 - is_modifiable: true - - id: 665 - code: resourceInstances - data_type: integer > 0 - required: true - default: "3" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `3`' - sort: 20 - is_modifiable: true - - id: 666 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 256 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 40 - is_modifiable: true - - id: 667 - code: resourceDisk - data_type: integer > 0 - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `10`' - man: Указывается в Gigabytes - sort: 50 - is_modifiable: true - - id: 668 - code: appVersion - data_type: string - required: true - default: 2.4.4 - value_list: - - 2.4.4 - descr: Выбрать из списка - sort: 60 - is_modifiable: true - - id: 669 - code: domain - data_type: string - required: true - default: bao- - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - name: create_kv - id: 212 - kind: subresource - action: create - subresource: kv - params: - - id: 675 - code: kvName - data_type: string - required: true - default: kvname- - regex: ^[a-zA-Z0-9-]{1,24}$ - man: Будет создан `v2 тип движка`

Уникальное в рамках услуги - sort: 10 - - name: create_policy - id: 237 - kind: subresource - action: create - subresource: policy - params: - - id: 728 - code: policySettings - data_type: array-map-fixed - required: true - sort: 20 - - id: 729 - code: policyName - required: true - default: policy- - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - man: Сделано для дальнейшего удобного использования - sort: 10 - - name: create_secrets - id: 214 - kind: subresource - action: create - subresource: secrets - params: - - id: 677 - code: kvName - data_type: string - required: true - descr: Выберите из списка - man: Если список пустой, создайте kv через операцию `create_kv` - sort: 10 - - id: 678 - code: secretPath - data_type: string - required: true - default: path/to/mysecret - regex: ^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$ - descr: 'Пример: `path` или `road/to/path`' - sort: 20 - - id: 679 - code: secretData - data_type: map - required: true - descr: Хотя бы один секрет необходимо добавить - man: Данные не сохраняются в ЛК, в дальнейшем при обновлении секретов это необходимо учитывать - sort: 30 - - name: delete - id: 231 - kind: instance - action: delete - params: [] - - name: delete_kv - id: 213 - kind: subresource - action: delete - subresource: kv - man: '**ОСТОРОЖНО**
Удаление KV подразумевает удаление ВСЕХ secrets внутри этой KV' - params: - - id: 676 - code: kvName - data_type: string - required: true - descr: Выберите из списка - sort: 10 - - name: delete_policy - id: 239 - kind: subresource - action: delete - subresource: policy - params: - - id: 732 - code: policyName - data_type: string - required: true - - name: delete_secrets - id: 233 - kind: subresource - action: delete - subresource: secrets - params: - - id: 726 - code: kvName - data_type: string - required: true - descr: Выберите из списка - sort: 10 - - id: 727 - code: secretPath - data_type: string - required: true - descr: Выберите из списка - sort: 20 - - name: modify - id: 211 - kind: instance - action: modify - params: - - id: 670 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `3`' - sort: 10 - - id: 671 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 8000 - minvalue: 250 - descr: 'Пример: `500`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 20 - - id: 672 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 256 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 30 - - id: 673 - code: resourceDisk - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `10`' - man: Указывается в Gigabytes - sort: 40 - - id: 674 - code: appVersion - data_type: string - required: true - value_list: - - 2.4.4 - descr: Выбрать из списка - sort: 50 - - name: reconcile - id: 236 - kind: action - action: reconcile - params: [] - - name: recovery_secrets - id: 232 - kind: action - action: recovery_secrets - man: Данная операция подразумевает откат на конкретную версию в секрете.

**Это не восстановление удалённого секрета** - params: - - id: 723 - code: kvName - data_type: string - required: true - descr: Выберите из списка - sort: 10 - - id: 724 - code: secretPath - data_type: string - required: true - descr: Выберите из списка - sort: 20 - - id: 725 - code: secretVersion - data_type: string - required: true - - name: restart - id: 234 - kind: action - action: restart - params: [] - - name: resume - id: 216 - kind: instance - action: resume - params: [] - - name: suspend - id: 215 - kind: instance - action: suspend - params: [] - - name: update_policy - id: 238 - kind: action - action: update_policy - params: - - id: 730 - code: policyName - data_type: string - required: true - sort: 10 - - id: 731 - code: policySettings - data_type: array-map-fixed - required: true - descr: Производится полная перезапись политики! - sort: 20 - - name: update_secrets - id: 230 - kind: action - action: update_secrets - params: - - id: 719 - code: kvName - data_type: string - required: true - descr: Выберите из списка - sort: 10 - - id: 720 - code: secretPath - data_type: string - required: true - descr: Выберите из списка - man: Предварительно необходимо выбрать параметр `Имя Key/Value хранилища` - sort: 20 - - id: 721 - code: needFullUpdateSecret - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - man: Если выбрать `true`, будет создана новая версия секрета `с нуля`
Если выбрать `false`, будет создана новая версия секрета с данными прошлой ревизии, а переданные данные в операции либо будут модифицированы, либо будут добавлены - sort: 30 - - id: 722 - code: secretData - data_type: map - required: true - descr: Хотя бы один секрет необходимо добавить - sort: 40 diff --git a/generated/dev/resources_yaml/153_nifi.yaml b/generated/dev/resources_yaml/153_nifi.yaml deleted file mode 100644 index a352f88..0000000 --- a/generated/dev/resources_yaml/153_nifi.yaml +++ /dev/null @@ -1,109 +0,0 @@ -name: nifi -service_id: 153 -service_display_name: Nifi -service_short_name: nifi -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 229 - kind: instance - action: create - params: - - id: 711 - code: domain - data_type: string - required: true - default: nifi- - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 712 - code: resourceCPU - data_type: integer > 0 - required: true - default: "2000" - maxvalue: 8000 - minvalue: 2000 - descr: 'Пример: `2000`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 30 - - id: 713 - code: resourceMemory - data_type: integer > 0 - required: true - default: "4096" - maxvalue: 16384 - minvalue: 2048 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 40 - - id: 714 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - value_list: - - "1" - maxvalue: 1 - minvalue: 1 - descr: 'Пример: `1`' - sort: 20 - - id: 715 - code: resourceDisk - data_type: integer > 0 - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `10`' - man: Указывается в Gigabytes - sort: 50 - - id: 716 - code: appVersion - data_type: string - required: true - default: 2.6.0 - value_list: - - 2.6.0 - descr: Выбрать из списка - sort: 60 - - id: 717 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Кластер Kubernetes в котором будет развёрнуто приложение - man: Выбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы - sort: 0 - - id: 718 - code: jdbcDrivers - data_type: array-map-fixed - required: true - man: 'Пример: `https://jdbc.postgresql.org/download/postgresql-42.7.8.jar`' - - name: delete - id: 235 - kind: instance - action: delete - params: [] diff --git a/generated/dev/resources_yaml/19_vc_org.yaml b/generated/dev/resources_yaml/19_vc_org.yaml deleted file mode 100644 index 666db83..0000000 --- a/generated/dev/resources_yaml/19_vc_org.yaml +++ /dev/null @@ -1,86 +0,0 @@ -name: vc_org -service_id: 19 -service_display_name: Организация в Cloud Director -service_short_name: vcOrg -service_man: '# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Url организации
Для быстрого доступа в тенант

### Статус организации
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)** привязанный к этой организации;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к vdc выше.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 136 - kind: instance - action: create - man: '`IaaS` - Доступ в Keycloak предоставляется пользователю, который создаёт услугу
`SaaS` - Без доступа к Keycloak' - params: - - id: 418 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Облако в котором будет развёрнут тенант - man: Выбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы - sort: 10 - - id: 556 - code: organizationType - data_type: string - required: true - default: iaas - value_list: - - iaas - - saas - man: Доступ к организации предоставляется только при выборе `iaas` - sort: 20 - - name: delete - id: 137 - kind: instance - action: delete - man: 'Удалить возможно только через 14 дней после выполнения операции `suspend`
**ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого тенанта**

Если существуют инстансы VDC, Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов' - params: [] - - name: modify - id: 207 - kind: instance - action: modify - man: Для возможности изменения параметров предварительно необходимо создать **Виртуальный датацентр (VDC)**, потом **Сетевой шлюз периметра (Edge Gateway)**
Также при удалении ipSpaces убедитесь, что все внешние IP удалены. В случае если хоть одна привязка vIP есть, данный ipSpace удалён **не будет** - params: - - id: 662 - code: vIPConfigure - data_type: array-map-fixed - required: true - default: '[{}]' - sort: 10 - - name: reconcile - id: 249 - kind: action - action: reconcile - params: [] - - name: resume - id: 144 - kind: instance - action: resume - params: [] - - name: suspend - id: 143 - kind: instance - action: suspend - man: Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри тенанта - params: [] diff --git a/generated/dev/resources_yaml/1_dummy.yaml b/generated/dev/resources_yaml/1_dummy.yaml deleted file mode 100644 index 30305c9..0000000 --- a/generated/dev/resources_yaml/1_dummy.yaml +++ /dev/null @@ -1,208 +0,0 @@ -name: dummy -service_id: 1 -service_display_name: Болванка -service_short_name: dummy -service_man: '## Болванка для тестов.

А это просто много букв, чтобы посмотреть, как ведет себя текст при переполнении контейнера.


``` json
{
"iamServiceUrl": "https://auth-api-test.ngcloud.ru/api/v1/user",
"idpResponse": {
"prefix": {
"charset": "",
"status_text": "Request Time-out",
"text": true,
"errordetail": "",
"filecontent": "Connection Timeout",
"responseheader": {},
"header": "",
"statuscode": "408 Request Time-out",
"status_code": 408,
"mimetype": "Unable to determine MIME type of file."
}
}
}
```' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 18 - kind: instance - action: create - man: Это мануал к операции CREATE сервиса Болванка - params: - - id: 198 - code: durationMs - data_type: integer >= 0 - required: true - default: "0" - descr: перед завершением подождать (sleep) столько миллисекунд - man: перед завершением подождать (sleep) столько миллисекунд - sort: 20 - is_modifiable: true - - id: 199 - code: failAtStart - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, завершить джоб, ничего не записывая в cmdb - man: '**Операция не будет завершена**
Она будет в постоянном статусе PENDING, однако в Jenkins Job завершится с ошибкой' - sort: 30 - is_modifiable: true - - id: 200 - code: failInProgress - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - man: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - sort: 40 - is_modifiable: true - - id: 201 - code: whereFail - data_type: integer > 0 - required: false - default: "1" - value_list: - - "1" - - "2" - - "3" - descr: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - man: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - sort: 50 - is_modifiable: true - - id: 242 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование ресурсной платформы для подключения - sort: 10 - - id: 286 - code: bodymessage - data_type: string - required: false - descr: Дата, уходящая в Vault - man: Дата, уходящая в Vault - sort: 60 - is_modifiable: true - - id: 321 - code: mapExample - data_type: map - required: false - is_modifiable: true - - id: 322 - code: jsonExample - data_type: json - required: false - descr: Для тестирования интерфейса - man: Для тестирования интерфейса. Сюда можно писать корректный json - is_modifiable: true - - id: 396 - code: nestedRefExample - required: false - - id: 447 - code: yamlExample - data_type: yaml - required: false - - id: 647 - code: mapFixed - data_type: map-fixed - required: false - descr: Новый тип поля - - id: 654 - code: arrayMapFixedExample - data_type: array-map-fixed - required: false - descr: Array of map-fixed - - name: delete - id: 71 - kind: instance - action: delete - params: [] - - name: modify - id: 92 - kind: instance - action: modify - params: - - id: 287 - code: durationMs - data_type: integer >= 0 - required: true - default: "0" - descr: перед завершением подождать (sleep) столько миллисекунд - man: перед завершением подождать (sleep) столько миллисекунд - sort: 10 - - id: 288 - code: failAtStart - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, завершить джоб, ничего не записывая в cmdb - sort: 20 - - id: 289 - code: failInProgress - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - sort: 30 - - id: 290 - code: whereFail - data_type: integer > 0 - required: false - value_list: - - "1" - - "2" - - "3" - descr: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - man: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - sort: 40 - - id: 291 - code: bodymessage - required: false - descr: Дата, уходящая в Vault - man: Дата, уходящая в Vault - sort: 50 - - id: 373 - code: mapExample - data_type: map - required: false - default: '{}' - - id: 374 - code: jsonExample - required: false - - name: reconcile - id: 257 - kind: action - action: reconcile - params: [] - - name: redeploy - id: 240 - kind: action - action: redeploy - params: [] - - name: resume - id: 94 - kind: instance - action: resume - params: [] - - name: suspend - id: 93 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/21_vc_vdc.yaml b/generated/dev/resources_yaml/21_vc_vdc.yaml deleted file mode 100644 index 4870b3a..0000000 --- a/generated/dev/resources_yaml/21_vc_vdc.yaml +++ /dev/null @@ -1,142 +0,0 @@ -name: vc_vdc -service_id: 21 -service_display_name: Виртуальный датацентр (vDC) -service_short_name: vc_vdc -service_man: '# Инструкция по развертыванию Виртуальный датацентр (vDC) через платформу

## 1. Общая информация

**Виртуальный датацентр (vDC)** — это логическая изолированная среда в VMware Cloud Director, предназначенная для размещения и управления виртуальными машинами, сетевой инфраструктурой и ресурсами хранения. Сервис обеспечивает выделение вычислительных ресурсов под конкретную организацию и предоставляет гибкие параметры масштабирования, контроля потребления и разделения ресурсов.

### Доступные операции

**create** — Создание виртуального датацентра (vDC) с заданными параметрами CPU, RAM, Storage и сетевой конфигурацией.
**delete** — Удаление vDC. Требуется предварительный перевод vDC в состояние *suspend*. Полное удаление возможно через 14 дней.
**modify** — Внесение изменений в параметры ресурсов (CPU/RAM/Storage), выделенных для vDC.
**suspend** — Заморозка vDC. Новые ресурсы или изменения внутри vDC становятся невозможными, работа ВМ не останавливается.
**resume** — Разморозка vDC. Восстановление возможности управления сущностями внутри vDC.

---

## 2. Параметры развертывания

Ниже перечислены входные параметры операции **create**.

### UUID Организации
Уникальный идентификатор организации в Cloud Director. Перед созданием vDC требуется предварительное создание услугу `Организация в Cloud Director`.

### Provider VDC в Cloud Director
Свойство ресурсной платформы, определяющее, какой пул физических ресурсов будет использоваться.

### Network Pool в Cloud Director
Определяет возможности сетевой конфигурации, включая создание Edge Gateway и выход во внешние сети.

### Гарантированная доля ЯДЕР
Гарантированный процент вычислительных ресурсов (CPU), закрепленный за vDC. Значение устанавливается разово при создании.

### Гарантированная доля ОЗУ
Гарантированный процент оперативной памяти, закрепленный за vDC. Также задаётся один раз при создании.

### Сколько аллоцировать на VDC ЯДЕР
Количество виртуальных ядер, выделяемых в рамках vDC.

### Сколько аллоцировать на VDC ОЗУ
Количество оперативной памяти в GB, выделяемой для vDC.

### Конфигурация Storage
Набор дисковых политик и их объёмов, выделяемых для vDC. Указывается имя политики и требуемый размер (GB).

---

## 3. Рекомендованные характеристики

### Тестовое окружение

- Количество ядер CPU: 10–20
- Аллоцируемая RAM: 16–64 GB
- Гарантированная доля CPU: 20%
- Гарантированная доля RAM: 20%
- Storage:
- Политика `SATA`
- Объём: 100–300 GB

### Промышленное окружение

- Количество ядер CPU: 16–128
- Аллоцируемая RAM: 64–512 GB
- Гарантированная доля CPU: 50%
- Гарантированная доля RAM: 50%
- Storage:
- Политики уровня `SSD`
- Объём: 1–10 TB, выбор несколько политик под разные нагрузки

---

## 4. Выходные параметры

Выходные параметры формируются операцией **create** (и используются другими операциями):

### Имя vDC
Уникальный идентификатор созданного виртуального датацентра. Используется в дальнейших операциях (modify, suspend, delete).

### Параметры выделенных ресурсов
Подтверждение итогового объёма CPU/RAM/Storage, выделенных vDC. Используются для учёта и контроля потребления.

---

## 5. Дополнительная информация

- Перед созданием vDC необходимо обеспечить наличие корректно созданной организации и доступных пула ресурсов ресурсной платформы.
- Гарантированная доля CPU и RAM задаётся **однократно при создании vDC**. После развертывания изменить эти значения невозможно; для изменения необходимо пересоздать vDC.
- Удаление vDC возможно только через **14 дней после перевода в состояние *suspend***. Удаление очищает все связанные сущности (ВМ, сети, каталоги), поэтому необходимо убедиться, что данные перенесены.
- Платформа Cloud Director использует концепцию изолированных организационных ресурсов, поэтому корректная настройка Provider VDC и Network Pool является обязательной при создании vDC.
- При изменении параметров (modify) изменяются только показатели CPU, RAM и Storage. Сетевые параметры и гарантированные доли остаются неизменными.
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 9 - kind: instance - action: create - params: - - id: 30 - code: organizationUid - data_type: uuid - required: true - ref_svc_id: 19 - man: Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` - sort: 10 - - id: 335 - code: providerVdc - data_type: string - required: true - man: Приписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
- sort: 30 - depends_on: organizationUid,networkProvider - - id: 361 - code: storageConfig - data_type: array-map-fixed - required: true - default: '[{}]' - man: Первая политика в списке указывается как "По умолчанию" - sort: 100 - is_modifiable: true - - id: 397 - code: cpuGuaranteed - data_type: integer > 0 - required: true - default: "20" - value_list: - - "20" - - "50" - - "80" - descr: '% резервирования' - man: Свойство нельзя изменить после создания - sort: 60 - - id: 557 - code: cpuAllocated - data_type: integer > 0 - required: true - default: "10" - maxvalue: 200 - minvalue: 1 - descr: шт - sort: 80 - is_modifiable: true - - id: 558 - code: memAllocated - data_type: integer > 0 - required: true - default: "20" - maxvalue: 4096 - minvalue: 1 - descr: gb - sort: 90 - is_modifiable: true - - id: 746 - code: networkProvider - data_type: string - required: true - sort: 20 - depends_on: organizationUid - - name: delete - id: 24 - kind: instance - action: delete - man: 'Удалить возможно только через 14 дней после выполнения операции `suspend`
**ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого VDC**

Если существуют инстансы Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов' - params: [] - - name: modify - id: 112 - kind: instance - action: modify - params: - - id: 560 - code: cpuAllocated - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: шт - sort: 10 - - id: 561 - code: memAllocated - data_type: integer > 0 - required: true - maxvalue: 1024 - minvalue: 1 - descr: gb - sort: 20 - - id: 562 - code: storageConfig - data_type: array-map-fixed - required: true - man: Первая политика в списке указывается как "По умолчанию" - sort: 30 - - name: reconcile - id: 250 - kind: action - action: reconcile - params: [] - - name: resume - id: 172 - kind: instance - action: resume - params: [] - - name: suspend - id: 171 - kind: instance - action: suspend - man: Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри VDC - params: [] diff --git a/generated/dev/resources_yaml/22_vc_nsxt.yaml b/generated/dev/resources_yaml/22_vc_nsxt.yaml deleted file mode 100644 index 4c2aaa3..0000000 --- a/generated/dev/resources_yaml/22_vc_nsxt.yaml +++ /dev/null @@ -1,136 +0,0 @@ -name: vc_nsxt -service_id: 22 -service_display_name: Сетевой шлюз периметра (Edge) -service_short_name: vc_nsxt -service_man: '# Инструкция по развертыванию Сетевой шлюз периметра (Edge) через платформу

## 1. Общая информация

Сервис **Сетевой шлюз периметра (Edge)** предназначен для создания периметрового сетевого шлюза в рамках одного виртуального датацентра (vDC) или группы виртуальных датацентров (groupvDC).
При создании автоматически разворачивается routed-сеть с адресным пространством `10.10.102.0/24`.
Сервис обеспечивает сетевую изоляцию, маршрутизацию, а также может включать функциональность балансировщика нагрузки AVI (ALB) для последующей интеграции, включая поддержку кластеров Штурвал.

### Доступные операции

**create** — Создание нового Edge с привязкой к vDC или groupvDC и развёртыванием routed-сети.
**delete** — Удаление ранее созданного Edge. Недоступно при наличии зависимых услуг (vApp, VM, Кластер Штурвал).
**modify** — Изменение параметров и сетевых настроек существующего Edge.

---

## 2. Параметры развертывания

Ниже приведены параметры операции **create**.

### Тип родительской услуги
Определяет контекст размещения Edge.
Допустимые значения: `vdc`, `groupvdc`.
Использование:
- При выборе `vdc` обязателен параметр **UUID VDC**.
- При выборе `groupvdc` обязателен параметр **UUID Группы VDC**.

### UUID VDC
Идентификатор виртуального датацентра.
Необходимо предварительно создать vDC через услугу «Виртуальный датацентр (vDC)».
Указывается только при выборе родительского типа `vdc`.

### UUID Группы VDC
Идентификатор группы виртуальных датацентров.
Создаётся через услугу «Группа виртуальных датацентров (groupvDC)».
Используется при выборе родительского типа `groupvdc`.

### Включить ALB
Флаг активации AVI Load Balancer в Cloud Director.
Пример значения: `true`/`false`.
Нужен для развёртывания кластера Штурвал и возможности создания Virtual Services.

### Наименование segroup
Имя сервиса групп (segroup) на уровне ресурсной платформы.
Обязательно при включённом ALB.
Определяет группу, в которой будут выделяться пулы AVI для Virtual Services.

### virtualServicesCount
Количество резервируемых виртуальных сервисов (Virtual Services) на AVI.
Типичное значение: 1–10 в зависимости от нагрузки.

---

## 3. Рекомендованные характеристики

### Тестовое окружение (Test)

- Тип родительской услуги: `vdc`
- virtualServicesCount: 1–2
- ALB: выключен по умолчанию (включать только при необходимости тестирования Штурвала)
- segroup: задаётся только при включённом ALB
- VDC гарантии CPU/RAM: минимальные (поскольку изменить их после создания нельзя)

### Промышленное окружение (Production)

- Тип родительской услуги: `groupvdc` при работе с распределёнными нагрузками или `vdc` для локализованных проектов
- virtualServicesCount: 3–10, исходя из предполагаемого количества публикаций
- ALB: включён, если требуется высокая доступность сервисов или используется кластер Штурвал
- segroup: рекомендуется использовать выделенную группу под проект
- VDC гарантии CPU/RAM: повышенные, с учётом того, что изменить их после создания невозможно без пересоздания vDC

---

## 4. Выходные параметры

### Имя Edge
Уникальное название созданного сетевого шлюза, используется для ссылок и дальнейших операций.

### Имя routed-сети
Автоматически созданная routed-сеть с подсетью `10.10.102.0/24`, используется для подключения ресурсов.

### Параметры Edge
Набор параметров, указанных пользователем при создании: тип услуги, ALB, segroup, virtualServicesCount и др.
Используются в операциях modify и для анализа состояния сервиса.

---

## 5. Дополнительная информация

- В рамках сервиса **один раз при создании задаётся гарантированная доля CPU/RAM vDC**. Изменить её невозможно — требуется пересоздание vDC.
- Удаление Edge недоступно при наличии зависимых ресурсов (vApp, VM, кластер Штурвал).
- При использовании ALB необходимо корректно указывать segroup, чтобы обеспечить корректное выделение пулов AVI.
- При выборе режима `groupvdc` следует учитывать распределение нагрузки между несколькими vDC.
- SNAT для всех ресурсов внутри Edge можно активировать через операцию modify (параметры выделения VIP и ipSpace).

' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 10 - kind: instance - action: create - params: - - id: 8 - code: vdcUid - data_type: string - required: false - ref_svc_id: 21 - descr: UUID Услуги `Виртуальный датацентр (vDC)` - man: 'Необходимо, если выбран тип подключаемой VDC: `vdc`' - sort: 10 - - id: 340 - code: needEnableAVI - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включение Load Balancer - man: Параметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указать - sort: 30 - is_modifiable: true - - id: 341 - code: virtualServicesCount - data_type: integer > 0 - required: false - default: "1" - maxvalue: 4 - minvalue: 1 - descr: Кол-во виртуальных сервисов, которые **резервируются** на AVI - man: Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB` - sort: 50 - is_modifiable: true - - id: 621 - code: vdcType - data_type: string - required: true - default: vdc - value_list: - - vdc - - vdcGroup - descr: Тип родительской услуги - man: При выборе vdc обеспечивает сетевую доступность только в рамках этого vdc
При выборе groupvdc обеспечивает сетевую доступность между всеми vdc, которые включены в groupvdc - sort: 0 - - id: 622 - code: vdcGroupUid - data_type: string - required: false - ref_svc_id: 29 - descr: UUID Услуги `Группа виртуальных датацентров (groupvDC)` - man: 'Необходимо, если выбран тип подключаемой VDC: `groupvdc`' - sort: 20 - - name: delete - id: 25 - kind: instance - action: delete - man: Невозможно удалить если routed-сеть в Edge связана с:
- vApp
- VM
- Kubernetes-кластер Штурвал

Запустить операцию возможно, но будет ошибка - params: [] - - name: modify - id: 111 - kind: instance - action: modify - man: Для создания SNAT Правила убедитесь, что в организации есть свободные IP
Редактировать кол-во свободных IP можно в услуге `Организация в Cloud Director` -> `modify` - params: - - id: 368 - code: needEnableAVI - data_type: boolean - required: false - value_list: - - "false" - - "true" - descr: Включение Load Balancer - man: Параметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указать - sort: 10 - - id: 369 - code: virtualServicesCount - data_type: integer > 0 - required: false - maxvalue: 4 - minvalue: 1 - descr: Кол-во виртуальных сервисов, которые выделяются на AVI - man: Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB` - sort: 30 - - id: 371 - code: needExternalAddressSNAT - data_type: boolean - required: false - value_list: - - "false" - - "true" - descr: Создать правило SNAT на подсеть `10.10.102.0/24` - man: Параметр `ip Space для VIP` станет обязательным, если указан `true` - sort: 40 - - id: 372 - code: ipSpaceName - data_type: string - required: false - descr: Имя ip Space для внешнего IP - man: Необходимо указывать, если включён параметр `Выделить VIP для SNAT` - sort: 50 - - name: reconcile - id: 252 - kind: action - action: reconcile - params: [] diff --git a/generated/dev/resources_yaml/25_vcexternalip.yaml b/generated/dev/resources_yaml/25_vcexternalip.yaml deleted file mode 100644 index eaa29b4..0000000 --- a/generated/dev/resources_yaml/25_vcexternalip.yaml +++ /dev/null @@ -1,162 +0,0 @@ -name: vcexternalip -service_id: 25 -service_display_name: Публичные IP адреса -service_short_name: vcexternalip -service_man: '**Обычно эта услуга разворачивается автоматически при развёртывании более сложных услуг**
Вручную создавать можно, однако услуга требует много параметров, о которых можно просто не знать

Резервировать публичные IP адреса можно только после создания NGcloud Organization, NGcloud Виртуальный датацентр, NGcloud Каталог, Сетевой шлюз периметра.
Вы можете назначить IP адрес для существующего экземпляра сервиса.' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 56 - kind: instance - action: create - params: - - id: 140 - code: serviceUid - data_type: string - required: true - sort: 20 - is_modifiable: true - - id: 141 - code: dnatCreate - data_type: boolean - required: true - default: "true" - descr: Необходимо создать DNAT-правило. - sort: 40 - is_modifiable: true - - id: 142 - code: internalPortAccess - data_type: string - required: true - default: "5432" - descr: Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
- sort: 60 - is_modifiable: true - - id: 143 - code: snatCreate - data_type: boolean - required: false - descr: Необходимо создать SNAT-правило.
- sort: 50 - is_modifiable: true - - id: 144 - code: internalAddrAccess - data_type: string - required: true - descr: Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true - sort: 70 - is_modifiable: true - - id: 324 - code: fromServiceNamespace - data_type: string - required: true - descr: Namespace составной услуги (для отображения правил FW) - sort: 80 - - id: 325 - code: fromServiceCloudEdgeName - data_type: string - required: false - descr: Edge составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 90 - - id: 326 - code: fromServiceCloudVdcName - required: false - descr: Vdc составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 100 - - id: 327 - code: fromServiceCloudOrgName - data_type: string - required: false - descr: Org составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 110 - - id: 328 - code: fromServiceCloudVmwareUrl - data_type: string - required: false - descr: Api-Url составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 120 - - id: 336 - code: ipSpaceName - data_type: string - required: true - descr: Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1) - sort: 30 - is_modifiable: true - - id: 488 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 200 - - id: 624 - code: fromServiceCloudEdgeScope - data_type: string - required: false - sort: 130 - - id: 626 - code: fromServiceVdcGroupName - data_type: string - required: false - sort: 140 - - name: delete - id: 57 - kind: instance - action: delete - params: [] - - name: modify - id: 197 - kind: instance - action: modify - params: - - id: 627 - code: serviceUid - data_type: string - required: true - sort: 20 - - id: 628 - code: ipSpaceName - data_type: string - required: true - sort: 30 - - id: 629 - code: dnatCreate - data_type: boolean - required: true - sort: 40 - - id: 630 - code: snatCreate - data_type: boolean - required: true - sort: 50 - - id: 631 - code: internalPortAccess - data_type: string - required: true - sort: 60 - - id: 632 - code: internalAddrAccess - data_type: string - required: true - sort: 70 diff --git a/generated/dev/resources_yaml/26_vapp.yaml b/generated/dev/resources_yaml/26_vapp.yaml deleted file mode 100644 index b48cabd..0000000 --- a/generated/dev/resources_yaml/26_vapp.yaml +++ /dev/null @@ -1,73 +0,0 @@ -name: vapp -service_id: 26 -service_display_name: Виртуальный каталог ВМ (vApp) -service_short_name: vapp -service_man: '# Инструкция по развертыванию Виртуальный каталог ВМ (vApp) через платформу

## 1. Общая информация

**Виртуальный каталог ВМ (vApp)** — это логическая каталог, объединённая в единый управляемый объект. Сервис предназначен для совместного развертывания, управления жизненным циклом и сетевого взаимодействия набора связанных ВМ. Основные функции включают:
- централизованное управление включением, выключением и приостановкой группы ВМ;
- унифицированный сетевой доступ через привязанный Edge-шлюз;

### Доступные операции

**create** — Создание нового vApp с привязкой к заданным услугам VDC и Edge
**delete** — Удаление существующего vApp. Требуется предварительный перевод vApp в состояние *suspend*. Полное удаление возможно через 14 дней.
**suspend** — Остановка vApp (выключение всех ВМ внутри каталога)
**resume** — Запуск vApp (включение всех ВМ внутри каталога)

---

## 2. Параметры развертывания

Параметры берутся из операции **create**.

### UUID Услуги VDC
Уникальный идентификатор услуги «Виртуальный датацентр (vDC)».
Используется для определения вычислительной инфраструктуры, в которой будет развернут vApp.

### UUID Услуги Edge
Уникальный идентификатор услуги «Сетевой шлюз периметра (Edge)».
Обеспечивает маршрутизацию и сетевое подключение. Может быть привязан к группе VDC, поэтому выбирается отдельно.

### Имя vApp
Строгое имя, соответствующее маске формирования DNS-имени.
Используется как часть в DNS-имени при создании виртуальных машин.

---

## 3. Рекомендованные характеристики
Так как является промежуточным этапом для создания ВМ, все характеристики описываются в услуге `Виртуальная машина`

---

## 4. Выходные параметры

### Параметры vApp
Заданные при создании vApp

---

## 5. Дополнительная информация

- Привязка к VDC и Edge осуществляется раздельно, поскольку один Edge может обслуживать несколько VDC (через услугу `Группа виртуальных датацентров (groupvDC)`). Это гарантирует возможность развернуть ВМ в единой сети, но в разных виртуальных датацентрах.
- Перед удалением vApp необходимо вручную перевести его в состояние **suspend**. Удаление возможно только спустя 14 дней после этого шага.
- Операция delete удаляет весь vApp полностью, включая все виртуальные машины, связанные с ним.
- Рекомендуется заранее планировать сетевые связи и назначения DNS-имён для обеспечения корректной работы сервисов, развернутых внутри vApp.
- При проектировании инфраструктуры следует учитывать зависимости между Edge-шлюзом, VDC и размещаемыми ВМ, чтобы избежать ограничений при масштабировании и интеграции.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 69 - kind: instance - action: create - params: - - id: 190 - code: nsxtUid - data_type: uuid - required: true - ref_svc_id: 22 - descr: UUID Услуги `Сетевой шлюз периметра (Edge)` - man: К какой сети может быть подключен виртуальный каталог - sort: 20 - - id: 191 - code: vappName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$ - minlength: 3 - descr: Уникальное в рамках организации - man: Имеет строгую маску `^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$`

Используется в формировании DNS-Имени (для виртуальных машин) - sort: 30 - - id: 623 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - descr: UUID Услуги `Виртуальный датацентр (vDC)` - man: В каких ресурсах будет создан виртуальный каталог - sort: 10 - - name: delete - id: 70 - kind: instance - action: delete - params: [] - - name: resume - id: 209 - kind: instance - action: resume - params: [] - - name: suspend - id: 208 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/28_vc_vm_v3.yaml b/generated/dev/resources_yaml/28_vc_vm_v3.yaml deleted file mode 100644 index e800f5a..0000000 --- a/generated/dev/resources_yaml/28_vc_vm_v3.yaml +++ /dev/null @@ -1,273 +0,0 @@ -name: vc_vm_v3 -service_id: 28 -service_display_name: Виртуальная машина -service_short_name: vc_vm_v3 -service_man: '# Документация по разворачиванию ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\ложь, определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed" (В нем не будет работать сбор метрик zabbix).

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 132 - kind: instance - action: create - man: '# Документация по использованию услуги развёртывания ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\лож определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed".

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики' - params: - - id: 407 - code: vappUid - data_type: uuid - required: true - ref_svc_id: 26 - sort: 10 - - id: 408 - code: vmName - data_type: string - required: true - default: web01 - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - sort: 20 - - id: 409 - code: vmCpu - data_type: integer > 0 - required: true - default: "1" - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 30 - is_modifiable: true - - id: 410 - code: vmRam - data_type: integer > 0 - required: true - default: "1" - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 40 - is_modifiable: true - - id: 411 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 50 - is_modifiable: true - - id: 412 - code: ipSpaceName - data_type: string - required: true - sort: 60 - depends_on: vappUid - is_modifiable: true - - id: 413 - code: accessIpList - data_type: json - required: false - regex: ^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$ - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 70 - is_modifiable: true - - id: 414 - code: imageVm - data_type: string - required: true - sort: 90 - depends_on: vappUid - - id: 415 - code: cloudInit - data_type: yaml - required: false - descr: Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. - sort: 200 - - id: 416 - code: userLogin - required: true - default: myuser - descr: Учётка SSH - sort: 180 - - id: 417 - code: userPublicKey - data_type: string - required: true - descr: Публичная часть SSH-Ключа для пользователя - sort: 190 - - id: 448 - code: accessPortList - data_type: string - required: true - default: '["22"]' - descr: 'По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX' - sort: 80 - is_modifiable: true - - name: delete - id: 133 - kind: instance - action: delete - params: [] - - name: modify - id: 159 - kind: instance - action: modify - params: - - id: 493 - code: vmCpu - data_type: integer > 0 - required: false - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 20 - - id: 494 - code: vmRam - data_type: integer > 0 - required: false - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 30 - - id: 495 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 40 - - id: 496 - code: ipSpaceName - data_type: string - required: false - value_list: - - no-needed - - internet-antiddos-v1 - - internet-no-antiddos-v1 - - internet-ipv4-v1 - descr: no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev - sort: 50 - - id: 497 - code: accessIpList - data_type: json - required: false - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 60 - - id: 498 - code: accessPortList - data_type: json - required: false - descr: Формат массива
По каким портам открыть доступ к ВМ.
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX - sort: 70 - - name: redeploy - id: 164 - kind: action - action: redeploy - params: - - id: 509 - code: vmName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - sort: 10 - - id: 510 - code: vmCpu - data_type: integer > 0 - required: true - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 20 - - id: 511 - code: vmRam - data_type: integer > 0 - required: true - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 30 - - id: 512 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 40 - - id: 513 - code: ipSpaceName - data_type: string - required: false - value_list: - - no-needed - - internet-antiddos-v1 - - internet-no-antiddos-v1 - - internet-ipv4-v1 - descr: no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev - sort: 50 - - id: 514 - code: accessIpList - data_type: json - required: false - regex: ^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$ - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 60 - - id: 515 - code: imageVm - data_type: string - required: true - value_list: - - RockyLinux_9-16G-cloudinit - - Ubuntu_22-20G - - Debian_13-20G - sort: 80 - - id: 516 - code: userLogin - data_type: string - required: true - descr: Учётка SSH - sort: 180 - - id: 517 - code: userPublicKey - data_type: string - required: true - descr: Публичная часть SSH-Ключа для пользователя - sort: 190 - - id: 518 - code: cloudInit - data_type: yaml - required: false - descr: Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. - sort: 200 - - id: 520 - code: accessPortList - data_type: json - required: false - descr: По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX - sort: 70 - - name: resume - id: 135 - kind: instance - action: resume - params: [] - - name: suspend - id: 134 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/29_vc_vdc_group.yaml b/generated/dev/resources_yaml/29_vc_vdc_group.yaml deleted file mode 100644 index efec3aa..0000000 --- a/generated/dev/resources_yaml/29_vc_vdc_group.yaml +++ /dev/null @@ -1,72 +0,0 @@ -name: vc_vdc_group -service_id: 29 -service_display_name: Группа датацентров -service_short_name: vcVdcGroup -service_man: '# Инструкция по развертыванию Группа виртуальных датацентров (groupvDC) через платформу

## 1. Общая информация

Сервис **Группа виртуальных датацентров (groupvDC)** предназначен для логического объединения нескольких виртуальных датацентров (vDC) в единую группу. Это позволяет растягивать SDN между разными vDC и централизованно управлять сетевой связностью. Управление инфраструктурой осуществляется через Cloud Director.
Сервис применяется в случаях, когда требуется обеспечить единое сетевое пространство для распределенных виртуальных датацентров.

### Доступные операции

**create** — Создание новой группы виртуальных датацентров.
**delete** — Удаление существующей группы vDC.
**add_vdc** — Добавление дополнительного виртуального датацентра в группу.
**remove_vdc** — Удаление ранее добавленного виртуального датацентра из группы.

---

## 2. Параметры развертывания

Параметры операции **create**:

### UUID VDC
Идентификатор виртуального датацентра, который будет являться первичным в группе.
Описание: требуется предварительно создать виртуальный датацентр с помощью услуги `Виртуальный датацентр (vDC)`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Для тестового окружения создавать группу VDC нет необходимости, так как это создаёт дополнительный слой абстракции в Cloud Director

### Промышленное окружение
- Для промышленного окружения, если в тенанте существуют разные VDC, создание groupvdc позволит снизить сетевые издержки (за счёт общей сети)

---

## 4. Выходные параметры

### Параметры groupvdc
Набор параметров, указанных пользователем при создании

---

## 5. Дополнительная информация
- Группа vDC используется для растягивания SDN между несколькими виртуальными датацентрами. Управление всеми сетевыми элементами внутри группы выполняется Cloud Director.
- Удалить первичный vDC (тот, что был указан при операции **create**) невозможно. Для его удаления необходимо удалить всю группу и создать новую.
- Перед добавлением любого vDC в группу он должен быть предварительно развернут через сервис `Виртуальный датацентр (vDC)`.
- Сети создаются не в этой услуге, а в услуге `Сетевой шлюз периметра (Edge)`. В ней необходимо будет выбрать тип `groupvdc`' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: add_vdc - id: 192 - kind: action - action: add_vdc - man: '**Не нужно** выбирать UUID VDC, который уже был добавлен в группу' - params: - - id: 619 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - sort: 10 - - name: create - id: 191 - kind: instance - action: create - man: '**VDC Группа** нужна для объединения всех VDC в организации в одну логическую группу.
Это позволит, к примеру, создать **общую сеть** для всех VDC в организации

- Для создания группы VDC необходимо указать **инстанс** услуги VDC (`Виртуальный датацентр`)
- **Важный момент** - удалить эту VDC из группы нельзя. Если такая потребность появится, необходимо будет **ПОЛНОСТЬЮ** удалить группу VDC и уже потом создать новую' - params: - - id: 618 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - sort: 10 - - name: delete - id: 195 - kind: instance - action: delete - params: [] - - name: reconcile - id: 251 - kind: action - action: reconcile - params: [] - - name: remove_vdc - id: 193 - kind: action - action: remove_vdc - params: - - id: 620 - code: vdcName - data_type: string - required: true - sort: 10 diff --git a/generated/dev/resources_yaml/2_template.yaml b/generated/dev/resources_yaml/2_template.yaml deleted file mode 100644 index d37f0bd..0000000 --- a/generated/dev/resources_yaml/2_template.yaml +++ /dev/null @@ -1,128 +0,0 @@ -name: template -service_id: 2 -service_display_name: Темплейт k8s -service_short_name: template -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 74 - kind: instance - action: create - params: - - id: 202 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 100 - is_modifiable: true - - id: 203 - code: resourceMemory - data_type: integer > 0 - required: true - default: "200" - maxvalue: 8192 - minvalue: 128 - is_modifiable: true - - id: 204 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - is_modifiable: true - - id: 205 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - is_modifiable: true - - id: 206 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - id: 207 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - - name: delete - id: 75 - kind: instance - action: delete - params: [] - - name: modify - id: 76 - kind: instance - action: modify - params: - - id: 208 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - - id: 209 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - - id: 210 - code: resourceDisk - data_type: integer > 0 - required: false - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - - id: 211 - code: resourceInstances - data_type: integer > 0 - required: false - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - - name: resume - id: 98 - kind: instance - action: resume - params: [] - - name: suspend - id: 97 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/50_nextcloud.yaml b/generated/dev/resources_yaml/50_nextcloud.yaml deleted file mode 100644 index b64448e..0000000 --- a/generated/dev/resources_yaml/50_nextcloud.yaml +++ /dev/null @@ -1,184 +0,0 @@ -name: nextcloud -service_id: 50 -service_display_name: Nextcloud -service_short_name: nextcloud -service_man: 'Ресурсная платформа: k8s. Автоматизация: helm chart' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 16 - kind: instance - action: create - man: DEV-Ветка сборки Nextcloud - params: - - id: 21 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Наименование домена. Если будет указан FQDN, то происходят проверки DNS. Если указан поддомен, то будет добавлен в зону services.ngcloud.ru
Можно указать клиентскую DNS-Запись. Важно, чтобы запись смотрела на Ingress кластера - sort: 10 - - id: 99 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili - man: Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili - sort: 30 - is_modifiable: true - - id: 100 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1024" - maxvalue: 8192 - minvalue: 1024 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 40 - is_modifiable: true - - id: 101 - code: resourceDisk - data_type: integer > 0 - required: true - default: "2" - maxvalue: 999 - minvalue: 2 - descr: Квота диска (Указывается в GIGAbytes)
Диск не может быть меньше 2G (!) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 192 - code: documentServer - data_type: string - required: true - default: collabora - value_list: - - collabora - descr: Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен
Размер пода collabora:
1.8 ядра. 2Gi ОЗУ - man: Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен - sort: 100 - - id: 470 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - value_list: - - "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов
Не может пока быть больше одного, так как нужны SC под RWMany - sort: 60 - is_modifiable: true - - id: 564 - code: psqlUid - data_type: uuid - required: true - ref_svc_id: 90 - sort: 6 - - id: 569 - code: appVersion - required: true - default: 32.0.1 - value_list: - - 32.0.1 - sort: 20 - is_modifiable: true - - id: 570 - code: redisUid - data_type: uuid - required: true - ref_svc_id: 91 - sort: 7 - - name: delete - id: 17 - kind: instance - action: delete - man: DEV-Ветка удаления Nextcloud - params: [] - - name: modify - id: 67 - kind: instance - action: modify - params: - - id: 178 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) - man: Квота ядра пода (Указывается в mili) - - id: 179 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - - id: 180 - code: resourceDisk - data_type: integer > 0 - required: false - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - - id: 547 - code: resourceInstances - data_type: integer > 0 - required: false - value_list: - - "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов.
Не может пока быть больше одного, так как нужны SC под RWMany - - id: 571 - code: appVersion - data_type: string - required: true - value_list: - - 32.0.1 - descr: Нельзя обновляться сразу через несколько версий сразу - - name: restart - id: 66 - kind: action - action: restart - params: [] - - name: resume - id: 129 - kind: instance - action: resume - params: [] - - name: suspend - id: 128 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/81_superset.yaml b/generated/dev/resources_yaml/81_superset.yaml deleted file mode 100644 index e935cbe..0000000 --- a/generated/dev/resources_yaml/81_superset.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: superset -service_id: 81 -service_display_name: Apache Superset -service_short_name: superset -service_man: 'Apache Superset как сервис.
Ресурсная платформа: k8s.
Автоматизация: k8s operator.
Авторизация: 2FA keycloak (для доменного логина @mgmt.nubes.ru)' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 12 - kind: instance - action: create - man: DEV-Ветка сборки Superset - params: - - id: 14 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 20 - code: emails - data_type: string - required: true - default: testuser1 - descr: Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - man: Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - sort: 70 - - id: 96 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - man: Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - sort: 30 - - id: 97 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 40 - - id: 98 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - - id: 109 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 227 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 60 - - name: delete - id: 13 - kind: instance - action: delete - man: DEV-Ветка удаления Superset - params: [] diff --git a/generated/dev/resources_yaml/82_harbor.yaml b/generated/dev/resources_yaml/82_harbor.yaml deleted file mode 100644 index c47b0df..0000000 --- a/generated/dev/resources_yaml/82_harbor.yaml +++ /dev/null @@ -1,103 +0,0 @@ -name: harbor -service_id: 82 -service_display_name: Container Registry -service_short_name: harbor -service_man: 'Расширенный реестр для управления Docker-образами с enterprise-функциями безопасности, репликации и контроля доступа.
Container Registry позволяет хранить, развертывать и управлять Docker-образами контейнеров в инфраструктуре NGcloud.
Сервис можно использовать в процессе разработки контейнеров. Например, вы можете настроить систему автоматизации на работу с реестром в Container Registry в рамках процесса непрерывной интеграции. Контейнеры идеально подходят для запуска небольших, независимых и легко изменяемых сервисов.
Чтобы начать работу, создайте реестр и загрузите в него Docker-образ
Авторизация: keycloak' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 14 - kind: instance - action: create - man: DEV-Ветка сборки Harbor - params: - - id: 16 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 20 - - id: 17 - code: emails - data_type: string - required: true - default: testuser1 - descr: Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел - man: Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел - sort: 70 - - id: 110 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 30 - - id: 228 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 40 - - id: 229 - code: resourceMemory - data_type: integer > 0 - required: true - default: "200" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 50 - - id: 230 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 60 - - id: 231 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: UUID экземпляра услуги S3 - man: UUID экземпляра услуги S3 - sort: 10 - - name: delete - id: 15 - kind: instance - action: delete - man: DEV-Ветка удаления Harbor - params: [] diff --git a/generated/dev/resources_yaml/88_k8s_ziti_controller.yaml b/generated/dev/resources_yaml/88_k8s_ziti_controller.yaml deleted file mode 100644 index 7270f20..0000000 --- a/generated/dev/resources_yaml/88_k8s_ziti_controller.yaml +++ /dev/null @@ -1,90 +0,0 @@ -name: k8s_ziti_controller -service_id: 88 -service_display_name: k8sZitiController -service_short_name: k8sZitiController -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 99 - kind: instance - action: create - params: - - id: 294 - code: resourceCPU - data_type: integer > 0 - required: true - default: "300" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - sort: 30 - - id: 295 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - sort: 40 - - id: 296 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - - id: 297 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 60 - - id: 298 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 20 - - id: 299 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - name: delete - id: 105 - kind: instance - action: delete - params: [] diff --git a/generated/dev/resources_yaml/89_flask.yaml b/generated/dev/resources_yaml/89_flask.yaml deleted file mode 100644 index 437d94d..0000000 --- a/generated/dev/resources_yaml/89_flask.yaml +++ /dev/null @@ -1,165 +0,0 @@ -name: flask -service_id: 89 -service_display_name: Web-сервер с фреймворком Flask -service_short_name: flask -service_man: '# Инструкция по развертыванию Web-сервер с фреймворком Flask через платформу

## 1. Общая информация

Сервис **Web-сервер с фреймворком Flask** предназначен для развертывания веб-приложений на базе Flask.

### Доступные операции

create — включить сервис, развернуть веб-приложение с указанными параметрами.
delete — удалить сервис, только после suspend.
modify — изменить настройки сервиса и переразвернуть.
suspend — выключить веб-приложение, остановить обслуживание.
resume — включить веб-приложение после suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Имя домена
Описание: доменное имя для доступа к веб-приложению. Если указан FQDN, происходит проверка DNS на валидность А-записи. А-запись должна указывать на балансировщик ресурсной платформы. Если указано имя в рамках одного октета, оно будет добавлено в публичную DNS-зону.
Пример значения: строка, допустимые FQDN или имя в одном октете. Пример: example.com или myapp.

### Платформа для развертывания
Описание: кластер Kubernetes, в котором будет развернуто приложение.
Пример значения: идентификатор кластера Kubernetes.

### Квота ядра пода
Описание: количество CPU, выделяемое на под, в Milicores.
Пример значения: целое число, например 500 для 0.5 ядра.

### Квота памяти пода
Описание: количество памяти, выделяемое на под, в Megabytes.
Пример значения: целое число, например 512 для 512 MB.

### Кол-во реплик пода
Описание: количество инстансов пода для масштабирования.
Пример значения: целое число, шт, например 2.

### URL Проекта (gitpath)
Описание: полный HTTPS путь до проекта в Git-репозитории.
Пример значения: URL в формате https://github.com/myuser/myproject.git. Доступ к репозиторию должен быть публичным.

### URL HealthCheck
Описание: путь для проверки здоровья приложения внутри пода.
Пример значения: строка, путь, например /api/v1/health.

### Переменные окружения пода
Описание: структура данных, которая будет передана как переменные окружения в под.
Пример значения: ключ-значение, например {"ENV": "production"}.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Квота ядра пода: 300m (0.3 ядра)
- Квота памяти пода: 256 MB
- Кол-во реплик пода: 1

### Промышленное окружение
- Квота ядра пода: от 1000m (1 ядро) в зависимости от нагрузки
- Квота памяти пода: от 1024 MB (1 GB) с учетом потребностей приложения
- Кол-во реплик пода: от 2 для обеспечения отказоустойчивости

---

## 4. Выходные параметры
Операция create не возвращает явных выходных параметров. Успешное выполнение операции приводит к развертыванию сервиса, доступного по указанному домену.

---

## 5. Дополнительная информация
- В корне проекта должен находиться файл requirements.txt со списком зависимостей Python.
- Исходный код веб-приложения должен располагаться в директории site.
- Запуск веб-сервера осуществляется командой python app.py.
- Используется версия Python: python:3.12-slim.
- Git-репозиторий должен быть публично доступен для платформы.
- Операция delete возможна только после suspend.
- Операция modify приводит к переразвертыванию с новыми параметрами.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 88 - kind: instance - action: create - params: - - id: 248 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - man: Если будет указан `FQDN`, то происходят проверки DNS на валидность А-записи. А-запись **обязана смотреть на балансировщик** ресурсной платформы.
Если указано имя `в рамках одного октета`, будет добавлено **в публичную днс-зону** - sort: 10 - - id: 249 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Кластер Kubernetes в котором будет развёрнуто приложение - man: Выбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы - sort: 20 - - id: 250 - code: resourceCPU - data_type: integer > 0 - required: true - default: "300" - maxvalue: 8000 - minvalue: 100 - descr: 'Пример: `1000`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 30 - is_modifiable: true - - id: 251 - code: resourceMemory - data_type: integer > 0 - required: true - default: "256" - maxvalue: 8192 - minvalue: 128 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 40 - is_modifiable: true - - id: 252 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `3`' - man: Балансировка производится между всеми репликами - sort: 50 - is_modifiable: true - - id: 253 - code: gitPath - data_type: string - required: true - default: https://github.com/Foxyhhd/Baldurs-Gate-test.git - descr: 'Пример: `https://github.com/myuser/myproject.git`' - man: Проект должен быть публичным - sort: 60 - is_modifiable: true - - id: 254 - code: jsonEnv - data_type: map - required: false - man: Структура, которая будет передана как переменные окружения - sort: 80 - is_modifiable: true - - id: 255 - code: healthPath - data_type: string - required: false - descr: 'Пример: `/api/v1/health`' - man: Может быть пустым. Если ничего не передано, проверяется `tcpsocket`
Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код - sort: 70 - - name: delete - id: 89 - kind: instance - action: delete - man: Удаление возможно только после остановки сервиса через операцию `suspend`
После выполнения операции необходимо выждать определенное кол-во времени - params: [] - - name: modify - id: 146 - kind: instance - action: modify - params: - - id: 451 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 8000 - minvalue: 100 - descr: 'Пример: `1000`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 10 - - id: 452 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 128 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 20 - - id: 453 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `3`' - man: Балансировка производится между всеми репликами - sort: 30 - - id: 454 - code: gitPath - required: true - descr: 'Пример: `https://github.com/myuser/myproject.git`' - man: Проект должен быть публичным - sort: 40 - - id: 455 - code: jsonEnv - data_type: map - required: true - man: Структура, которая будет передана как переменные окружения - sort: 50 - - name: resume - id: 145 - kind: instance - action: resume - params: [] - - name: suspend - id: 125 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/90_postgres.yaml b/generated/dev/resources_yaml/90_postgres.yaml deleted file mode 100644 index 7811991..0000000 --- a/generated/dev/resources_yaml/90_postgres.yaml +++ /dev/null @@ -1,519 +0,0 @@ -name: postgres -service_id: 90 -service_display_name: PostgreSQL -service_short_name: postgres -service_man: '# Инструкция по развертыванию PostgreSQL через платформу

---
## 1. Общая информация

PostgreSQL — это надёжная объектно-реляционная СУБД с открытым исходным кодом, поддерживающая расширенный набор функций, транзакции и хранение сложных типов данных. Развёртывание полностью автоматизировано платформой на базе Zalando Postgres Operator с использованием Kubernetes.

## Доступные операции

- **create** — Создание кластера
- **delete** — Удаление кластера
- **modify** — Модификация кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера
- **restart** — Перезапуск кластера
- **recovery** — Восстановление из резервной копии

- **create_user** — Создание пользователя
- **delete_user** — Удаление пользователя

- **create_database** — Создание базы данных
- **delete_database** — Удаление базы данных


---
## 2. Параметры развертывания кластера

Ниже перечислены параметры, которые необходимо указать при создании ресурса PostgreSQL:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество инстансов (реплик) в кластере PostgreSQL. Пример: `2` (master + slave).

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных в гигабайтах. Пример: `20`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`

* **Выделяет внешний IP для доступа к slave:**
Флаг для выделения внешнего IP для slave (реплики чтения). Работает, если slave присутствует в кластере.

* **Имя ipSpace для публикации внешнего IP slave:**
Если включен параметр для slave, то поле необходимо заполнить.

* **UUID экземпляра услуги S3:**
UUID экземпляра S3 для хранения резервных копий.

* **Версия PostgreSQL:**
Версия PostgreSQL для развертывания. Пример: `16`

* **Расписание бэкапов (ext_BACKUP_SCHEDULE):**
Необязательный. Cron-выражение для времени запуска бэкапов. По умолчанию: `0 0 * * *` (ежедневно в полночь).

* **Количество сохраняемых бэкапов (ext_BACKUP_NUM_TO_RETAIN):**
Необязательный. Количество сохраняемых бэкапов. По умолчанию: `7`

* **PgPooler (master / slave):**
Флаги включения PgBouncer для подключений на запись и чтение. При включении создаётся отдельный под.

* **Разрешить подключение без SSL (allowNoSSL):**
По умолчанию подключение с sslmode=require. При `true` разрешается подключение без SSL.

* **Автоскейлинг PV (autoScale):**
Включает автоскейлинг тома. Требует настройки autoScalePercentage, autoScaleTechWindow, autoScaleQuotaGb.

* **Дополнительные параметры PostgreSQL (jsonParameters):**
JSON с переменными конфигурации PostgreSQL. Документация: https://www.postgresql.org/docs/current/runtime-config.html

---
## 3. Выходные параметры

После успешного развертывания ресурса PostgreSQL платформа возвращает ряд параметров.

#### externalConnect

Внешние эндпоинты для подключения к кластеру:
- **master** — для операций записи (host: `write.${namespace}`, port: 5432)
- **slave** — для операций чтения (host: `read.${namespace}`, port: 5432)

Пример ответа платформы:

```json
{
"slave": {
"ip": "",
"fqdn": "",
"uuid": "",
"isExternal": false
},
"master": {
"ip": "<ip>",
"fqdn": "write.<namespace>.<cluster-domain>",
"uuid": "<uuid>",
"isExternal": false
}
}
```

Поля: `ip` — внешний IP; `fqdn` — полное имя хоста; `uuid` — идентификатор; `isExternal` — признак внешнего доступа.

#### internalConnect

Внутренние эндпоинты (FQDN) для подключения из других сервисов внутри той же сети Kubernetes.

Пример ответа платформы:

```json
{
"slave": "",
"master": {
"slave": "",
"master": {
"slave": "",
"master": "postgresqlk8s-master.<namespace>.svc.cluster.local"
}
}
}
```

Для подключения используйте значение `master.master.master` (host для записи) или соответствующее значение slave (host для чтения).

Для подключения используется порт **5432**.

---
## 4. Управление пользователями

### create_user — Создание пользователя

* **Имя пользователя (username):**
Имя создаваемого пользователя. Используется для подключения к базе и настройки прав.
Пример: `myapp_user`

* **Роль (role):**
Тип роли пользователя. Допустимые значения:
- `app_user` — базовые права для DML-операций (SELECT, INSERT, UPDATE, DELETE)
- `ddl_user` — расширенные права: createdb, createrole (управление базами и ролями)

Защищённые имена, которые нельзя использовать: `admin`, `postgres`, `standby`.

### delete_user — Удаление пользователя

* **Имя пользователя (username):**
Имя удаляемого пользователя. Пример: `myapp_user`

Пользователя нельзя удалить, если он является владельцем базы данных. Сначала удалите или передайте владение базами данных другому пользователю.

---
## 5. Управление базами данных

### create_database — Создание базы данных

* **Имя базы данных (dbName):**
Название создаваемой базы данных. Пример: `myapp_db`

* **Владелец базы данных (dbOwner):**
Имя пользователя-владельца базы. Должен существовать в кластере (создан через create_user). Пример: `myapp_user`

### delete_database — Удаление базы данных

* **Имя базы данных (dbName):**
Название удаляемой базы данных. Пример: `myapp_db`
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 19 - kind: instance - action: create - man: руководство - params: - - id: 23 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - man: Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - sort: 20 - - id: 80 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - regex: ^[1357]$ - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в кластере. 1,3,5,7 - sort: 60 - is_modifiable: true - - id: 81 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 82 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - man: Квота ядра пода (milicores) - sort: 30 - is_modifiable: true - - id: 83 - code: resourceDisk - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 102 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Кластер Kubernetes, на котором будет развернут экземпляр - sort: 10 - - id: 145 - code: needExternalAddressMaster - data_type: boolean - required: false - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к master - man: Выделяет внешний (белый) IP для доступа к master - sort: 70 - is_modifiable: true - - id: 146 - code: needExternalAddressSlave - data_type: boolean - required: false - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть - man: Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть - sort: 90 - is_modifiable: true - - id: 265 - code: ext_BACKUP_SCHEDULE - data_type: string - required: false - default: 0 0 * * * - regex: ^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$ - man: Не обязательный. Время запуска бекапа - sort: 150 - is_modifiable: true - - id: 266 - code: ext_BACKUP_NUM_TO_RETAIN - data_type: integer > 0 - required: false - default: "7" - maxvalue: 99 - minvalue: 1 - man: Не обязательный. Количество сохраняемых бекапов - sort: 140 - is_modifiable: true - - id: 310 - code: appVersion - data_type: string - required: true - default: "17" - value_list: - - "17" - - "16" - descr: Версия PostgreSQL - sort: 160 - is_modifiable: true - - id: 311 - code: jsonParameters - data_type: json - required: true - default: '{ "log_connections": "off", "log_disconnections": "off" }' - maxlength: 2048 - descr: Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html - sort: 170 - is_modifiable: true - - id: 312 - code: enablePgPoolerMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает pgPooler (на запись). Будет создан новый под - sort: 180 - is_modifiable: true - - id: 313 - code: enablePgPoolerSlave - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает pgPooler (на чтение). Будет создан новый под - sort: 190 - is_modifiable: true - - id: 314 - code: allowNoSSL - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр - sort: 200 - is_modifiable: true - - id: 329 - code: autoScale - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги - sort: 300 - - id: 330 - code: autoScalePercentage - data_type: integer > 0 - required: true - default: "10" - value_list: - - "10" - - "15" - - "20" - descr: Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема - sort: 310 - - id: 331 - code: autoScaleTechWindow - data_type: integer >= 0 - required: true - default: "0" - value_list: - - "0" - - "5" - - "12" - - "23" - descr: Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) - sort: 320 - - id: 337 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`' - sort: 80 - is_modifiable: true - - id: 338 - code: ipSpaceNameSlave - data_type: string - required: false - descr: Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave - sort: 100 - is_modifiable: true - - id: 339 - code: autoScaleQuotaGb - data_type: string - required: true - default: "1" - descr: Квота для autoScale - sort: 330 - - name: create_database - id: 245 - kind: subresource - action: create - subresource: database - params: - - id: 741 - code: dbName - data_type: string - required: true - - id: 742 - code: dbOwner - data_type: string - required: true - - name: create_user - id: 241 - kind: subresource - action: create - subresource: user - params: - - id: 733 - code: username - data_type: string - required: true - regex: ^(?![0-9_])[a-zA-Z_][a-zA-Z0-9_]{0,62}$ - maxlength: 62 - minlength: 2 - - id: 740 - code: role - data_type: string - required: true - value_list: - - app_user - - ddl_user - descr: Выбрать роль из списка - man: '`app_user` — стандартный пользователь с базовым набором прав
`ddl_user` — пользователь с расширенными правами, включая управление ролями и базами данных' - - name: delete - id: 20 - kind: instance - action: delete - params: - - id: 457 - code: deleteS3Bucket - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Также удалить технический S3 Bucket с бэкапами? - sort: 10 - - name: delete_database - id: 246 - kind: subresource - action: delete - subresource: database - params: - - id: 743 - code: dbName - data_type: string - required: true - - name: delete_user - id: 244 - kind: subresource - action: delete - subresource: user - params: - - id: 739 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - - name: modify - id: 48 - kind: instance - action: modify - params: - - id: 91 - code: resourceInstances - data_type: integer > 0 - required: false - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 40 - - id: 92 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 20 - - id: 93 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - man: Квота ядра пода (milicores) - sort: 10 - - id: 94 - code: resourceDisk - data_type: integer > 0 - required: false - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 30 - - id: 147 - code: needExternalAddressMaster - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Выделяет внешний IP для доступа к master - man: Выделяет внешний IP для доступа к master - sort: 50 - - id: 148 - code: needExternalAddressSlave - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Выделяет внешний IP для доступа к slave. Действует, если slave в принципе есть - man: Выделяет внешний IP для доступа к slave. Действует, если slave в принципе есть - sort: 70 - - id: 267 - code: ext_BACKUP_SCHEDULE - data_type: string - required: false - regex: ^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$ - man: Не обязательный. Время запуска бекапа - sort: 90 - - id: 268 - code: ext_BACKUP_NUM_TO_RETAIN - data_type: integer > 0 - required: false - maxvalue: 99 - minvalue: 1 - man: Не обязательный. Количество сохраняемых бекапов - sort: 100 - - id: 315 - code: appVersion - data_type: string - required: true - value_list: - - "17" - - "16" - descr: Версия PostgreSQL. Нельзя опускать вниз - sort: 110 - - id: 316 - code: jsonParameters - data_type: json - required: false - maxlength: 2048 - descr: Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html - sort: 120 - - id: 317 - code: enablePgPoolerMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает pgPooler (на запись). Будет создан новый под - sort: 130 - - id: 318 - code: enablePgPoolerSlave - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает pgPooler (на чтение). Будет создан новый под - sort: 140 - - id: 319 - code: allowNoSSL - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр - sort: 150 - - id: 541 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`' - sort: 60 - - id: 542 - code: ipSpaceNameSlave - data_type: string - required: false - descr: Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave - sort: 80 - - name: recovery - id: 47 - kind: action - action: recovery - params: - - id: 86 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети
- sort: 50 - - id: 87 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes)
- man: Квота памяти пода (Указывается в Megabytes)
- sort: 30 - - id: 88 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili)
- man: Квота ядра пода (Указывается в mili)
- sort: 20 - - id: 89 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 40 - - id: 131 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 10 - - name: restart - id: 54 - kind: action - action: restart - man: ВНИМАНИЕ - Рестарт предполагает УДАЛЕНИЕ подов.
Может быть полная поломка. Крайне осторожно запускать при работе - params: [] - - name: resume - id: 114 - kind: instance - action: resume - params: [] - - name: suspend - id: 115 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/91_redis.yaml b/generated/dev/resources_yaml/91_redis.yaml deleted file mode 100644 index a710a58..0000000 --- a/generated/dev/resources_yaml/91_redis.yaml +++ /dev/null @@ -1,118 +0,0 @@ -name: redis -service_id: 91 -service_display_name: Redis -service_short_name: redis -service_man: 'Redis кластер. Под кеши.
Ресурсная платформа: k8s.
Автоматизация: k8s operator
port 6379' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 21 - kind: instance - action: create - params: - - id: 112 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (Указывается в mili) - man: Квота ядра пода (Указывается в mili) - sort: 20 - - id: 113 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1024" - maxvalue: 8192 - minvalue: 512 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 30 - - id: 114 - code: resourceDisk - data_type: integer > 0 - required: true - default: "30" - maxvalue: 999 - minvalue: 10 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 40 - - id: 181 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети. Если выделить больше 1 ноды, будет добавлено дополнительно 3 Sentinel ноды - sort: 50 - - id: 182 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения
- sort: 10 - - id: 183 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний IP для доступа к master - man: Выделяет внешний IP для доступа к master - sort: 60 - - id: 184 - code: needExternalAddressSlave - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть - man: Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть - sort: 70 - - id: 548 - code: ipSpaceNameMaster - data_type: string - required: false - descr: Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster - - id: 549 - code: ipSpaceNameSlave - data_type: string - required: false - descr: Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave - - name: delete - id: 22 - kind: instance - action: delete - params: [] diff --git a/generated/dev/resources_yaml/92_mongodb.yaml b/generated/dev/resources_yaml/92_mongodb.yaml deleted file mode 100644 index 9f4a36e..0000000 --- a/generated/dev/resources_yaml/92_mongodb.yaml +++ /dev/null @@ -1,185 +0,0 @@ -name: mongodb -service_id: 92 -service_display_name: MongoDB -service_short_name: mongodb -service_man: '# Инструкция по развертыванию MongoDB через платформу

## 1. Общая информация

MongoDB — документоориентированная распределённая база данных, обеспечивающая высокую доступность, горизонтальное масштабирование и гибкую модель хранения.

### Доступные операции с кластером

* **create** — создание базы
* **delete** — удаление базы данных
* **suspend** — остановка базы данных
* **resume** — запуск базы данных
* **modify** — изменение базы данных

### Доступные операции с пользователями

* **create_user** — создание пользователя
* **modify_user** — модификация пользователя
* **delete_user** — удаление пользователя

---

## 2. Параметры развертывания базы данных

Эти параметры необходимо указать при создании базы данных.

### Платформа для развертывания

Среда, в которой будет развернут кластер. Выбирается из предложенного списка.

### Количество узлов

Оптимально выбирать нечётное количество узлов в кластере MongoDB, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность базы данных даже при отказе одной из нод.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных в гигабайтах.
Пример: `20`

### Выделение внешнего IP для доступа к master

Флаг, определяющий необходимость выделения внешнего IP.
Допустимые значения: `true` или `false`

### Имя ipSpace для публикации внешнего IP

Указывается только если включено выделение внешнего IP.
Пример: `internet-no-antiddos-v1`

---

## 3. Параметры модификации базы данных

Все параметры, которые вы указываете при модификации, являются необязательными — система автоматически подставит ранее сохранённые значения, и при необходимости вы можете изменить их на нужные.

### Количество узлов

Оптимально выбирать нечётное количество узлов в кластере MongoDB, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность базы данных даже при отказе одной из нод.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных указывается в гигабайтах. Его можно увеличить при необходимости, однако уменьшить уже выделенный размер невозможно.
Пример: `20`

### Выделение внешнего IP для доступа к master

Флаг, определяющий необходимость выделения внешнего IP.
Допустимые значения: `true` или `false`

### Имя ipSpace для публикации внешнего IP

Указывается только если включено выделение внешнего IP.
Пример: `internet-no-antiddos-v1`

---

## 3. Параметры создания пользователя

### Имя пользователя

Указывается имя пользователя (любой регистр).
Пример: `readApp`

### Имя базы данных

Название базы, в которой будет создан пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read** — доступ только на чтение
* **readWrite** — чтение и изменение данных
* **dbOwner** — полный контроль над базой данных

---

## 4. Параметры модификации пользователя

### Имя пользователя

Необходимо выбрать существующего пользователя.
Если список пуст, требуется предварительно создать пользователя.

### Имя базы данных

База данных, к которой относится пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read**
* **readWrite**
* **dbOwner**

---

## 5. Параметры удаления пользователя

### Имя пользователя

Выберите пользователя из списка для удаления.

---

## 6. Выходные параметры

После успешного развертывания базы данных платформа возвращает ключевые параметры.

### internalConnect

Внутренний эндпоинт для подключения к кластеру из сервисов, работающих в той же сети.
Используется для внутренних интеграций и системных сервисов.

### externalConnect

Внешний FQDN для подключения к кластеру извне.
Порт подключения — **27017**.

---

## 7. Пример подключения

Перед подключением необходимо установить **mongosh**.

Команда подключения к базе данных:

```
mongosh "mongodb://<username>:<password>@<endpoint_db>:27017/<dbName>"
```

Где:

* `<username>` — имя пользователя
* `<password>` — пароль
* `<endpoint_db>` — internalConnect или externalConnect
* `<dbName>` — имя базы данных

## 8. Дополнительная информация

Сейчас соединение с базой работает без шифрования, и доступ к кластеру осуществляется только по логину и паролю.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 37 - kind: instance - action: create - params: - - id: 487 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `2`' - sort: 10 - is_modifiable: true - - id: 588 - code: resourceMemory - data_type: integer > 0 - required: true - minvalue: 500 - descr: 'Пример: `2048`' - is_modifiable: true - - id: 589 - code: resourceCPU - data_type: integer > 0 - required: true - descr: 'Пример: `1000`' - is_modifiable: true - - id: 590 - code: resourceDisk - data_type: integer > 0 - required: true - descr: 'Пример: `20`' - is_modifiable: true - - id: 595 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 645 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`' - is_modifiable: true - - id: 646 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - is_modifiable: true - - name: create_user - id: 198 - kind: subresource - action: create - subresource: user - params: - - id: 635 - code: username - data_type: string - required: true - - id: 636 - code: dbName - data_type: string - required: true - - id: 643 - code: role - data_type: string - required: true - value_list: - - dbOwner - - read - - readWrite - - name: delete - id: 190 - kind: instance - action: delete - params: [] - - name: delete_user - id: 199 - kind: subresource - action: delete - subresource: user - params: - - id: 644 - code: username - data_type: string - required: true - - name: modify - id: 201 - kind: instance - action: modify - params: - - id: 648 - code: resourceInstances - data_type: integer > 0 - required: false - descr: 'Пример: `2`' - - id: 649 - code: resourceMemory - data_type: integer > 0 - required: false - descr: 'Пример: `2048`' - - id: 650 - code: resourceCPU - data_type: integer > 0 - required: false - descr: 'Пример: `1000`' - - id: 651 - code: resourceDisk - data_type: integer > 0 - required: false - descr: 'Пример: `20`' - - id: 652 - code: needExternalAddressMaster - data_type: boolean - required: false - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`' - - id: 653 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - - name: modify_user - id: 200 - kind: subresource - action: modify - subresource: user - params: - - id: 640 - code: username - data_type: string - required: true - - id: 641 - code: dbName - data_type: string - required: true - - id: 642 - code: role - data_type: string - required: true - value_list: - - dbOwner - - read - - readWrite - - name: resume - id: 196 - kind: instance - action: resume - params: [] - - name: suspend - id: 194 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/93_rabbitmq.yaml b/generated/dev/resources_yaml/93_rabbitmq.yaml deleted file mode 100644 index 50da006..0000000 --- a/generated/dev/resources_yaml/93_rabbitmq.yaml +++ /dev/null @@ -1,164 +0,0 @@ -name: rabbitmq -service_id: 93 -service_display_name: RabbitMQ -service_short_name: rabbitmq -service_man: '# Инструкция по развертыванию RabbitMQ через платформу

---
## 1. Общая информация
RabbitMQ — это брокер сообщений с открытым исходным кодом, который обеспечивает надёжную доставку сообщений между приложениями.
Позволяет надёжно передавать сообщения между сервисами и системами, интегрироваться с внешними решениями и использовать как внутренние, так и защищённые TLS-подключения. Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание кластера
- **modify** — Изменение параметров кластера
- **delete** — Удаление кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера


---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса RabbitMQ:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество реплик в кластере RabbitMQ. При значении больше 1 создаётся кластер с репликацией для обеспечения высокой доступности.
Пример: `1` (single node) или `3` (кластер с репликацией)

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных RabbitMQ в гигабайтах. Пример: `50`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-узлу. При включении создаётся Service типа LoadBalancer и настраивается VIP на порту 5672.
Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`


---
## 3. Модификация кластера
Операция **modify** позволяет изменить параметры существующего кластера RabbitMQ.

**Изменяемые параметры:**
* **Квота (megabyte) памяти пода** — можно увеличить или уменьшить
* **Квота (millicore) ядра пода** — можно увеличить или уменьшить
* **Размер (gigabyte) диска для базы данных** — можно только увеличить (уменьшение не поддерживается)
* **Количество узлов в сети** — можно только увеличить (уменьшение не поддерживается)
* **Выделяет внешний IP для доступа к master** — можно включить или выключить
* **Имя ipSpace для публикации внешнего IP master** — можно изменить при включенном внешнем IP

**Ограничения:**
* Уменьшение размера диска не поддерживается
* Уменьшение количества реплик не поддерживается

---
## 4. Выходные параметры
После успешного развертывания ресурса RabbitMQ платформа возвращает ряд параметров в разделе "Поля состояния (сгенерированные значения)":

**clusterDomain**
Домен кластера Kubernetes, в котором развернут RabbitMQ.
Пример: `cluster.local`

**inernalConnect**
Внутренние эндпоинты для подключения к кластеру RabbitMQ из других сервисов, развернутых внутри той же сети.
Содержит:
* **master** — FQDN для подключения к кластеру. Пример: `rabbitmqk8s.{namespace}.svc.{clusterDomain}`

**externalConnect**
Внешние эндпоинты для подключения к кластеру RabbitMQ извне.
Содержит объекты с полями:
* **admin** — доступ к веб-интерфейсу управления:
* `fqdn` — полное доменное имя для веб-интерфейса. Пример: `admin.{namespace}.{domain}`
* `ip` — IP-адрес
* **master** — доступ к AMQP протоколу (если включен внешний IP):
* `fqdn` — полное доменное имя для AMQP. Пример: `write.{namespace}.{domain}`
* `ip` — IP-адрес

**monitoring**
Информация о дашбордах мониторинга:
* **allDashboards** — URL для доступа ко всем дашбордам Grafana

Для подключения используются следующие порты:

* **5672** — AMQP протокол (внутренний и внешний доступ, если включен внешний IP)
* **15672** — веб-интерфейс управления (доступен через Ingress по HTTPS)

**Учётные данные**
Данные для подключения к RabbitMQ доступны в разделе "Учётные данные":
* **adminUser** — имя пользователя администратора
* **adminPass** — пароль администратора


---
## 5. Примеры подключения через консоль (rabbitmqadmin)

### Работа с очередями через rabbitmqadmin

Для работы с RabbitMQ через консоль используется утилита `rabbitmqadmin`. Установите её или используйте образ с предустановленной утилитой.

Задайте переменные окружения с учётными данными:

```bash
export RABBITMQ_USERNAME=<adminUser>
export RABBITMQ_PASSWORD=<adminPass>
export RABBIT_HOST=<host>
```

Где:
* `<adminUser>` и `<adminPass>` — учётные данные из раздела "Учётные данные"
* `<host>` — адрес для подключения:
* Для внешнего подключения: `externalConnect.admin.fqdn` или `externalConnect.master.fqdn`

**Создание очереди:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
declare queue name=healthcheck durable=false
```

**Листинг очередей:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
list queues
```

**Отправка сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
publish exchange=amq.default routing_key=healthcheck payload="ping-$(date +%s)"
```

**Чтение сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
get queue=healthcheck ackmode=ack_requeue_false
```

---
## 6. Дополнительная информация
Для подключения к кластеру RabbitMQ используйте полученные эндпоинты из раздела "Поля состояния (сгенерированные значения)" и учётные данные из раздела "Учётные данные".

Веб-интерфейс управления доступен по адресу, указанному в параметре `externalConnect.admin.fqdn` через HTTPS.

Для внутреннего подключения используйте адрес из `inernalConnect.master` на порту 5672.

---' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 38 - kind: instance - action: create - params: - - id: 116 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 4000 - minvalue: 500 - descr: 'Пример: `2000`' - sort: 20 - is_modifiable: true - - id: 117 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1124" - maxvalue: 8192 - minvalue: 512 - descr: 'Пример: `2048`' - sort: 30 - is_modifiable: true - - id: 118 - code: resourceDisk - data_type: integer > 0 - required: true - default: "30" - maxvalue: 999 - minvalue: 5 - descr: 'Пример: `20`' - sort: 40 - is_modifiable: true - - id: 119 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 224 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - sort: 50 - is_modifiable: true - - id: 225 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`' - sort: 60 - is_modifiable: true - - id: 543 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - is_modifiable: true - - name: delete - id: 39 - kind: instance - action: delete - params: [] - - name: modify - id: 106 - kind: instance - action: modify - params: - - id: 304 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 4000 - minvalue: 500 - descr: 'Пример: `2000`' - sort: 10 - - id: 305 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 512 - descr: 'Пример: `2048`' - sort: 20 - - id: 306 - code: resourceDisk - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `20`' - sort: 10 - - id: 307 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - sort: 40 - - id: 308 - code: needExternalAddressMaster - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к master - sort: 50 - - id: 545 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - - name: resume - id: 117 - kind: instance - action: resume - params: [] - - name: suspend - id: 116 - kind: instance - action: suspend - man: Пока не работает из за того что RabbitmqCluster нельзя занулить - params: [] diff --git a/generated/dev/resources_yaml/94_lucee.yaml b/generated/dev/resources_yaml/94_lucee.yaml deleted file mode 100644 index 5ec0c17..0000000 --- a/generated/dev/resources_yaml/94_lucee.yaml +++ /dev/null @@ -1,217 +0,0 @@ -name: lucee -service_id: 94 -service_display_name: Lucee -service_short_name: lucee -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 49 - kind: instance - action: create - params: - - id: 103 - code: domain - data_type: string - required: true - default: lucee- - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 104 - code: gitPath - data_type: string - required: true - default: https://github.com/xahys/testlucee - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 60 - is_modifiable: true - - id: 105 - code: jsonEnv - data_type: json - required: false - default: '{ "param": "value" }' - maxlength: 2048 - descr: Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения. - sort: 70 - is_modifiable: true - - id: 106 - code: resourceCPU - data_type: integer > 0 - required: true - default: "300" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - man: Квота ядра пода (milicores) - sort: 30 - is_modifiable: true - - id: 107 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 108 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 132 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код - man: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код - sort: 80 - is_modifiable: true - - id: 139 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 50 - is_modifiable: true - - id: 263 - code: appVersion - data_type: string - required: true - default: "5.4" - value_list: - - "5.4" - - "6.0" - regex: ^\d+(\.\d+){1,2}(-[a-zA-Z0-9\.]+)?$ - descr: Версия Lucee - sort: 90 - is_modifiable: true - - name: delete - id: 50 - kind: instance - action: delete - params: [] - - name: modify - id: 55 - kind: instance - action: modify - man: Если CFS оставить пустым, то при запуске джобы берётся параметр из instanceData - params: - - id: 133 - code: gitPath - data_type: string - required: false - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 50 - - id: 134 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. - man: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. - sort: 60 - - id: 135 - code: jsonEnv - data_type: json - required: false - maxlength: 2048 - descr: Массив переменных, будут переданы в env приложения - man: Массив переменных, будут переданы в env приложения - sort: 40 - - id: 136 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) 1000Mili = 1 ядро - man: Квота ядра пода (Указывается в mili) - sort: 10 - - id: 137 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 20 - - id: 138 - code: resourceInstances - data_type: integer > 0 - required: false - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 30 - - id: 264 - code: appVersion - data_type: string - required: true - default: "5.4" - value_list: - - "5.4" - - "6.0" - regex: ^\d+(\.\d+){1,2}(-[a-zA-Z0-9\.]+)?$ - sort: 70 - - name: redeploy - id: 53 - kind: action - action: redeploy - params: - - id: 257 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: restart - id: 163 - kind: action - action: restart - params: [] - - name: resume - id: 95 - kind: instance - action: resume - params: [] - - name: suspend - id: 96 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/95_nodejs.yaml b/generated/dev/resources_yaml/95_nodejs.yaml deleted file mode 100644 index c387870..0000000 --- a/generated/dev/resources_yaml/95_nodejs.yaml +++ /dev/null @@ -1,215 +0,0 @@ -name: nodejs -service_id: 95 -service_display_name: NodeJS -service_short_name: nodejs -service_man: Развертывает контейнер в k8s кластере с node, который можно использовать для запуска своих приложений.
Приложение должно быть доступно по ссылки в git репозитории, которая является входным параметром. -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 58 - kind: instance - action: create - params: - - id: 149 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Наименование поддомена, будет добавлено в nodejs.dev.nubes.ru - sort: 10 - - id: 150 - code: gitPath - data_type: string - required: true - default: https://github.com/xahys/testnode.git - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 60 - is_modifiable: true - - id: 151 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет - man: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет - sort: 80 - is_modifiable: true - - id: 152 - code: jsonEnv - data_type: json - required: false - descr: Массив переменных, будут переданы в env приложения - man: Массив переменных, будут переданы в env приложения - sort: 70 - is_modifiable: true - - id: 153 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores). 1000Mili = 1 Ядро - man: Квота ядра пода (milicores). 1000Mili = 1 Ядро - sort: 30 - is_modifiable: true - - id: 154 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1024" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 155 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 50 - is_modifiable: true - - id: 156 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 20 - - id: 270 - code: appVersion - data_type: string - required: true - default: "23" - value_list: - - "18" - - "20" - - "22" - - "23" - regex: ^(\d){2}$ - descr: Версия приложения - sort: 90 - is_modifiable: true - - name: delete - id: 61 - kind: instance - action: delete - params: [] - - name: modify - id: 59 - kind: instance - action: modify - params: - - id: 157 - code: gitPath - data_type: string - required: false - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 50 - - id: 158 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. - man: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. - sort: 60 - - id: 159 - code: jsonEnv - data_type: json - required: false - maxlength: 2048 - descr: Массив переменных, будут переданы в env приложения - man: Массив переменных, будут переданы в env приложения - sort: 40 - - id: 160 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) 1000Mili = 1 ядро - man: Квота ядра пода (Указывается в mili) 1000Mili = 1 ядро - sort: 10 - - id: 161 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 20 - - id: 162 - code: resourceInstances - data_type: integer > 0 - required: false - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 30 - - id: 271 - code: appVersion - data_type: string - required: true - default: "23" - value_list: - - "18" - - "20" - - "22" - - "23" - regex: ^(\d){2}$ - descr: Версия приложения - man: Версия приложения - sort: 70 - - name: redeploy - id: 60 - kind: action - action: redeploy - params: - - id: 258 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: resume - id: 121 - kind: instance - action: resume - params: [] - - name: suspend - id: 120 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/96_pgadmin.yaml b/generated/dev/resources_yaml/96_pgadmin.yaml deleted file mode 100644 index 336df63..0000000 --- a/generated/dev/resources_yaml/96_pgadmin.yaml +++ /dev/null @@ -1,158 +0,0 @@ -name: pgadmin -service_id: 96 -service_display_name: pgAdmin -service_short_name: pgadmin -service_man: Инструмент с графическим интерфейсом для управления базами данных PostgreSQL -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 62 - kind: instance - action: create - params: - - id: 164 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 165 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (milicores). 1000Mili = 1 Ядро - man: Квота ядра пода (milicores). 1000Mili = 1 Ядро - sort: 30 - is_modifiable: true - - id: 166 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 512 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 167 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 169 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 170 - code: login - data_type: string - required: true - regex: ^([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)$ - maxlength: 255 - minlength: 3 - descr: Логин для подключения к pgAdmin, в формате email (login@email.net) - man: Логин для подключения к pgAdmin, в формате email (login@email.net) - sort: 60 - - id: 171 - code: password - data_type: string - required: true - descr: Пароль для подключения к pgAdmin - man: Пароль для подключения к pgAdmin - sort: 70 - is_sensitive: true - - name: delete - id: 63 - kind: instance - action: delete - params: [] - - name: modify - id: 64 - kind: instance - action: modify - params: - - id: 172 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - - id: 173 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - - id: 174 - code: resourceDisk - data_type: integer > 0 - required: false - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - - name: redeploy - id: 65 - kind: action - action: redeploy - params: - - id: 277 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: resume - id: 123 - kind: instance - action: resume - params: [] - - name: suspend - id: 122 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/97_nodered.yaml b/generated/dev/resources_yaml/97_nodered.yaml deleted file mode 100644 index 4edaed8..0000000 --- a/generated/dev/resources_yaml/97_nodered.yaml +++ /dev/null @@ -1,91 +0,0 @@ -name: nodered -service_id: 97 -service_display_name: NodeRed -service_short_name: nodered -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 72 - kind: instance - action: create - params: - - id: 193 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 30 - - id: 194 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - sort: 40 - - id: 195 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 60 - - id: 196 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 197 - code: domain - data_type: string - required: true - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - man: Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - sort: 10 - - id: 323 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 50 - - name: delete - id: 73 - kind: instance - action: delete - params: [] diff --git a/generated/dev/resources_yaml/98_http.yaml b/generated/dev/resources_yaml/98_http.yaml deleted file mode 100644 index 58a9db9..0000000 --- a/generated/dev/resources_yaml/98_http.yaml +++ /dev/null @@ -1,150 +0,0 @@ -name: http -service_id: 98 -service_display_name: Простой HTTP контейнер -service_short_name: http -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 77 - kind: instance - action: create - params: - - id: 212 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 213 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) - man: Квота ядра пода (Указывается в mili) - sort: 30 - is_modifiable: true - - id: 214 - code: resourceMemory - data_type: integer > 0 - required: true - default: "200" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 40 - is_modifiable: true - - id: 215 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество реплик приложения. Трафик будет распределяться между подами в режиме Round-Robin - sort: 50 - is_modifiable: true - - id: 216 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 217 - code: registryPath - data_type: string - required: true - default: nexus-sa.tst.nubes.ru/docker-nubes/jolt - descr: Путь до image, который будет установлен как deployment - man: Путь до image, который будет установлен как deployment - sort: 60 - - id: 241 - code: jsonEnv - data_type: json - required: false - default: '{"param": "value"}' - descr: Массив переменных, будут переданы в env приложения - man: Массив переменных, будут переданы в env приложения - sort: 70 - - name: delete - id: 78 - kind: instance - action: delete - params: [] - - name: modify - id: 81 - kind: instance - action: modify - params: - - id: 218 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 4000 - minvalue: 100 - - id: 219 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 128 - - id: 220 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - - name: redeploy - id: 79 - kind: action - action: redeploy - params: - - id: 272 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 10 - - name: resume - id: 130 - kind: instance - action: resume - params: [] - - name: suspend - id: 131 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/99_gitea.yaml b/generated/dev/resources_yaml/99_gitea.yaml deleted file mode 100644 index 87f9cb9..0000000 --- a/generated/dev/resources_yaml/99_gitea.yaml +++ /dev/null @@ -1,153 +0,0 @@ -name: gitea -service_id: 99 -service_display_name: Gitea -service_short_name: gitea -service_man: Развертывает сервис контроля версий Gitea
Зависит от сервиса postgresql который должен быть развернут заранее. -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 82 - kind: instance - action: create - params: - - id: 232 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 300 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 40 - is_modifiable: true - - id: 233 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 256 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 50 - is_modifiable: true - - id: 234 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 60 - is_modifiable: true - - id: 235 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 70 - is_modifiable: true - - id: 237 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 20 - - id: 238 - code: psqlUid - data_type: uuid - required: true - ref_svc_id: 90 - descr: UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - man: UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - sort: 10 - - name: delete - id: 83 - kind: instance - action: delete - params: [] - - name: modify - id: 91 - kind: instance - action: modify - params: - - id: 259 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 10 - - id: 260 - code: resourceMemory - data_type: integer > 0 - required: true - default: "128" - maxvalue: 8192 - minvalue: 256 - descr: Квота памяти пода (Указывается в Megabytes) - sort: 20 - - id: 261 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 30 - - id: 262 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 40 - - name: resume - id: 127 - kind: instance - action: resume - params: [] - - name: suspend - id: 126 - kind: instance - action: suspend - params: [] diff --git a/generated/dev/resources_yaml/embed.go b/generated/dev/resources_yaml/embed.go deleted file mode 100644 index 72e3ff2..0000000 --- a/generated/dev/resources_yaml/embed.go +++ /dev/null @@ -1,8 +0,0 @@ -package resources_yaml - -import "embed" - -// Files embeds unified service YAML specs for provider runtime lookup. -// -//go:embed *.yaml -var Files embed.FS diff --git a/generated/dev/tmp/.gitkeep b/generated/dev/tmp/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/prod/docs/.gitkeep b/generated/prod/docs/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/prod/docs/akhq.md b/generated/prod/docs/akhq.md deleted file mode 100644 index b160ca3..0000000 --- a/generated/prod/docs/akhq.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## MAN - -
-# Инструкция по развертыванию Apache Kafka через платформу

---
## 1. Общая информация
AKHQ — это веб-интерфейс для работы с кластерами Apache Kafka.
Позволяет просматривать топики, consumer group'ы, сообщения, ACL, схему безопасности, состояние брокеров и метаданные.
Поддерживает работу с несколькими кластерами Kafka одновременно, включая внутренние и внешние (TLS) подключения.

## Доступные операции
- **create** — Создание ресурса AKHQ
- **suspend** — Остановка ресурса
- **resume** — Возобновление работы ресурса
- **modify** — Модификация настроек
- **delete** — Удаление ресурса

---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса Kafka:

* **Кластер Kafka к которому нужно настроить подключение**
Для использования AKHQ необходимо предварительно развернуть сервис Kafka. Пример: `kafka-external`.

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество узлов для работы Akhq. Пример `2`

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `512`

* **Квота (millicore ) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `500`

* **Имя домена:**
Dns Имя по которому будет происходить обращение к сервису. Указать необходимо уникальное имя до . ( то есть если необходимо получить dns ui) Пример: `kafka-external`

---
## 4. Выходные параметры
После успешного развертывания ресурса Kafka платформа возвращает ряд параметров.
Ключевым из них является:

**connectionUrl**
Это полное доменное имя (FQDN), по которому будет доступен интерфейс AKHQ. После развёртывания подождите несколько минут — UI станет доступен по HTTPS, как только все сервисы полностью запустятся.

**Учетные данные**
Здесь представлены поля для ввода логина и пароля, с помощью которых вы сможете авторизоваться в сервисе.

---
## 5. Дополнительная информация
Учётные записи, созданные для работы с AKHQ, предоставляют доступ только для просмотра данных. Для управления Kafka, пожалуйста, используйте возможности личного кабинета.
--- -
diff --git a/generated/prod/docs/akhq_example.md b/generated/prod/docs/akhq_example.md deleted file mode 100644 index 71302f1..0000000 --- a/generated/prod/docs/akhq_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Copy-ready manifest (`akhq_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_akhq" "baza" { - resource_realm = "TODO" # Выбрать платформу из списка - domain = "TODO" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - kafka_uid = "TODO" # Выбрать кластер из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_memory = 512 # Пример: `1024` - resource_cpu = 500 # Пример: `1000` - resource_instances = 1 -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_akhq.baza.state_params["имя_ключа"] -nubes_akhq.baza.state_out["имя_ключа"] -nubes_akhq.baza.state_params_flat["имя_ключа"] -nubes_akhq.baza.state_out_flat["имя_ключа"] -nubes_akhq.baza.vault_secrets["имя_ключа"] -nubes_akhq.baza.vault_url -nubes_akhq.baza.vault_user_path -nubes_akhq.baza.vault_fields -``` diff --git a/generated/prod/docs/akhq_ops.md b/generated/prod/docs/akhq_ops.md deleted file mode 100644 index 9e4364f..0000000 --- a/generated/prod/docs/akhq_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](akhq_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](akhq_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/akhq_outputs.md b/generated/prod/docs/akhq_outputs.md deleted file mode 100644 index 22405f5..0000000 --- a/generated/prod/docs/akhq_outputs.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` - -### `vault_secrets` ключи - -- `vault_secrets["pass"]` -- `vault_secrets["user"]` - diff --git a/generated/prod/docs/akhq_params.md b/generated/prod/docs/akhq_params.md deleted file mode 100644 index b419cf6..0000000 --- a/generated/prod/docs/akhq_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Parameters - -- [Create params](akhq_params_create.md) -- [Modify params](akhq_params_modify.md) diff --git a/generated/prod/docs/akhq_params_create.md b/generated/prod/docs/akhq_params_create.md deleted file mode 100644 index 687ca12..0000000 --- a/generated/prod/docs/akhq_params_create.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
550resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
553domainstringЕсли будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
555kafka_uiduuidВыбрать кластер из спискаref_svc_id=116
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
551resource_memoryinteger512Пример: `1024`minvalue=512
552resource_cpuinteger500Пример: `1000`minvalue=500
554resource_instancesinteger1minvalue=1
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/akhq_params_modify.md b/generated/prod/docs/akhq_params_modify.md deleted file mode 100644 index 1ba2657..0000000 --- a/generated/prod/docs/akhq_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
565kafka_uiduuidВыбрать кластер из спискаref_svc_id=116
diff --git a/generated/prod/docs/dnsrecord.md b/generated/prod/docs/dnsrecord.md deleted file mode 100644 index 22f9734..0000000 --- a/generated/prod/docs/dnsrecord.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## MAN - -
-Необходима DNS зона, в которой будет создана DNS запись.
Выберите
* Зону в которой будет создана запись
* Тип записи
* Имя записи
* Значение записи -
diff --git a/generated/prod/docs/dnsrecord_example.md b/generated/prod/docs/dnsrecord_example.md deleted file mode 100644 index 4f3667e..0000000 --- a/generated/prod/docs/dnsrecord_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Copy-ready manifest (`dnsrecord_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_dnsrecord" "baza" { - zone_uid = "TODO" # UUID экземпляра услуги DNS-зоны - record_type = "A" # Тип DNS-записи - record_name = "TODO" # Имя записи. Имя зоны в конце проставляется автоматически - record_input = "TODO" # Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - record_ttl = 3600 # Time-to-Leave записи. Раз в какое время запись будет обновлена -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dnsrecord.baza.state_params["имя_ключа"] -nubes_dnsrecord.baza.state_out["имя_ключа"] -nubes_dnsrecord.baza.state_params_flat["имя_ключа"] -nubes_dnsrecord.baza.state_out_flat["имя_ключа"] -nubes_dnsrecord.baza.vault_secrets["имя_ключа"] -nubes_dnsrecord.baza.vault_url -nubes_dnsrecord.baza.vault_user_path -nubes_dnsrecord.baza.vault_fields -``` diff --git a/generated/prod/docs/dnsrecord_ops.md b/generated/prod/docs/dnsrecord_ops.md deleted file mode 100644 index 475844c..0000000 --- a/generated/prod/docs/dnsrecord_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dnsrecord_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](dnsrecord_params_modify.md) diff --git a/generated/prod/docs/dnsrecord_outputs.md b/generated/prod/docs/dnsrecord_outputs.md deleted file mode 100644 index 4d127c2..0000000 --- a/generated/prod/docs/dnsrecord_outputs.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dnsServers"]` -- `state_out_flat["record"]` - diff --git a/generated/prod/docs/dnsrecord_params.md b/generated/prod/docs/dnsrecord_params.md deleted file mode 100644 index 84701f9..0000000 --- a/generated/prod/docs/dnsrecord_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Parameters - -- [Create params](dnsrecord_params_create.md) -- [Modify params](dnsrecord_params_modify.md) diff --git a/generated/prod/docs/dnsrecord_params_create.md b/generated/prod/docs/dnsrecord_params_create.md deleted file mode 100644 index b3a67ca..0000000 --- a/generated/prod/docs/dnsrecord_params_create.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
75zone_uiduuidUUID экземпляра услуги DNS-зоныref_svc_id=110
76record_typestringТип DNS-записиvalue_list=A, AAAA, CNAME, MX, PTR, SOA, SRV, TXT, LUA, NS, SSHFP
77record_namestringИмя записи. Имя зоны в конце проставляется автоматическиunique_scope=parent
78record_inputstringЗначение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
450record_ttlinteger3600Time-to-Leave записи. Раз в какое время запись будет обновленаminvalue=30; maxvalue=604800
diff --git a/generated/prod/docs/dnsrecord_params_modify.md b/generated/prod/docs/dnsrecord_params_modify.md deleted file mode 100644 index d3cdbdb..0000000 --- a/generated/prod/docs/dnsrecord_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
256record_inputstringЗапись. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP
diff --git a/generated/prod/docs/dnszone.md b/generated/prod/docs/dnszone.md deleted file mode 100644 index f8249dd..0000000 --- a/generated/prod/docs/dnszone.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## MAN - -
-## ![image](https://img.icons8.com/?size=50&id=41400&format=png) Необходимо делегировать зону у регистратора на Авторитетные DNS (Сервера зон)

ns3.ngcloud.ru
``` bash
185.247.187.83
2a10:aa80:0:5::3
```

ns4.ngcloud.ru
``` bash
81.22.46.43
2a10:aa80:0:6::3
``` -
diff --git a/generated/prod/docs/dnszone_example.md b/generated/prod/docs/dnszone_example.md deleted file mode 100644 index 04c2bca..0000000 --- a/generated/prod/docs/dnszone_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Copy-ready manifest (`dnszone_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_dnszone" "baza" { - zone_email = "TODO" # Контактный e-mail - zone_name = "TODO" # Имя зоны - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - zone_kind = "NATIVE" # Тип зоны - zone_time_to_refresh = 86400 # Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов - zone_time_to_retry = 7200 # Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов - zone_time_to_expire = 3600000 # Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным - zone_time_to_live = 86400 # Время, в течение которого информация будет кешироваться другими DNS-серверами -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dnszone.baza.state_params["имя_ключа"] -nubes_dnszone.baza.state_out["имя_ключа"] -nubes_dnszone.baza.state_params_flat["имя_ключа"] -nubes_dnszone.baza.state_out_flat["имя_ключа"] -nubes_dnszone.baza.vault_secrets["имя_ключа"] -nubes_dnszone.baza.vault_url -nubes_dnszone.baza.vault_user_path -nubes_dnszone.baza.vault_fields -``` diff --git a/generated/prod/docs/dnszone_ops.md b/generated/prod/docs/dnszone_ops.md deleted file mode 100644 index e07344c..0000000 --- a/generated/prod/docs/dnszone_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dnszone_params_create.md) -- `delete` diff --git a/generated/prod/docs/dnszone_outputs.md b/generated/prod/docs/dnszone_outputs.md deleted file mode 100644 index 0c3556d..0000000 --- a/generated/prod/docs/dnszone_outputs.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dnsServers"]` -- `state_out_flat["dnsServers.ns1.nubes.ru"]` -- `state_out_flat["dnsServers.ns2.nubes.ru"]` -- `state_out_flat["zoneSerial"]` -- `state_out_flat["zoneSoaServer"]` - diff --git a/generated/prod/docs/dnszone_params.md b/generated/prod/docs/dnszone_params.md deleted file mode 100644 index 0f1f739..0000000 --- a/generated/prod/docs/dnszone_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Parameters - -- [Create params](dnszone_params_create.md) -- [Modify params](dnszone_params_modify.md) diff --git a/generated/prod/docs/dnszone_params_create.md b/generated/prod/docs/dnszone_params_create.md deleted file mode 100644 index 0690a8f..0000000 --- a/generated/prod/docs/dnszone_params_create.md +++ /dev/null @@ -1,31 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
66zone_emailstringКонтактный e-mail
67zone_namestringИмя зоныregex=^([a-z0-9-]+\.)+[a-z0-9-]+$
69zone_masters_for_slavestringИспользовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов
284resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
68zone_kindstringNATIVEТип зоныvalue_list=NATIVE, SLAVE
70zone_time_to_refreshstring86400Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов
71zone_time_to_retrystring7200Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов
72zone_time_to_expirestring3600000Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным
73zone_time_to_livestring86400Время, в течение которого информация будет кешироваться другими DNS-серверами
diff --git a/generated/prod/docs/dnszone_params_modify.md b/generated/prod/docs/dnszone_params_modify.md deleted file mode 100644 index bd1dc13..0000000 --- a/generated/prod/docs/dnszone_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/dummy.md b/generated/prod/docs/dummy.md deleted file mode 100644 index 53f9855..0000000 --- a/generated/prod/docs/dummy.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## MAN - -
-## Болванка для тестов.

А это просто много букв, чтобы посмотреть, как ведет себя текст при переполнении контейнера.


``` json
{
"iamServiceUrl": "https://auth-api-test.ngcloud.ru/api/v1/user",
"idpResponse": {
"prefix": {
"charset": "",
"status_text": "Request Time-out",
"text": true,
"errordetail": "",
"filecontent": "Connection Timeout",
"responseheader": {},
"header": "",
"statuscode": "408 Request Time-out",
"status_code": 408,
"mimetype": "Unable to determine MIME type of file."
}
}
}
``` -
diff --git a/generated/prod/docs/dummy_example.md b/generated/prod/docs/dummy_example.md deleted file mode 100644 index 4f60ba3..0000000 --- a/generated/prod/docs/dummy_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Copy-ready manifest (`dummy_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_dummy" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - duration_ms = 0 # перед завершением подождать (sleep) столько миллисекунд - fail_at_start = false # если true, завершить джоб, ничего не записывая в cmdb - fail_in_progress = false # если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - where_fail = 1 # принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dummy.baza.state_params["имя_ключа"] -nubes_dummy.baza.state_out["имя_ключа"] -nubes_dummy.baza.state_params_flat["имя_ключа"] -nubes_dummy.baza.state_out_flat["имя_ключа"] -nubes_dummy.baza.vault_secrets["имя_ключа"] -nubes_dummy.baza.vault_url -nubes_dummy.baza.vault_user_path -nubes_dummy.baza.vault_fields -``` diff --git a/generated/prod/docs/dummy_ops.md b/generated/prod/docs/dummy_ops.md deleted file mode 100644 index 2cd4d8f..0000000 --- a/generated/prod/docs/dummy_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dummy_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](dummy_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/prod/docs/dummy_outputs.md b/generated/prod/docs/dummy_outputs.md deleted file mode 100644 index 52b99e1..0000000 --- a/generated/prod/docs/dummy_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `vault_secrets` ключи - -- `vault_secrets["someKey"]` - diff --git a/generated/prod/docs/dummy_params.md b/generated/prod/docs/dummy_params.md deleted file mode 100644 index 67ae088..0000000 --- a/generated/prod/docs/dummy_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Parameters - -- [Create params](dummy_params_create.md) -- [Modify params](dummy_params_modify.md) diff --git a/generated/prod/docs/dummy_params_create.md b/generated/prod/docs/dummy_params_create.md deleted file mode 100644 index a098d0b..0000000 --- a/generated/prod/docs/dummy_params_create.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
242resource_realmstringНаименование ресурсной платформы для подключенияfunc=getAvailableResourceRealms
286bodymessagestringДата, уходящая в Vault
321map_examplemap
322json_examplejsonДля тестирования интерфейса. Сюда можно писать корректный json
396nested_ref_example
447yaml_exampleyaml
647map_fixedmap-fixedНовый тип поля
654array_map_fixed_examplearray-map-fixedArray of map-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
198duration_msinteger0перед завершением подождать (sleep) столько миллисекунд
199fail_at_startbooleanfalse**Операция не будет завершена**
Она будет в постоянном статусе PENDING, однако в Jenkins Job завершится с ошибкой
value_list=false, true
200fail_in_progressbooleanfalseесли true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdbvalue_list=false, true
201where_failinteger1принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault writevalue_list=1, 2, 3
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/dummy_params_modify.md b/generated/prod/docs/dummy_params_modify.md deleted file mode 100644 index b601221..0000000 --- a/generated/prod/docs/dummy_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
287duration_msintegerперед завершением подождать (sleep) столько миллисекунд
288fail_at_startbooleanесли true, завершить джоб, ничего не записывая в cmdbvalue_list=false, true
289fail_in_progressbooleanесли true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdbvalue_list=false, true
290where_failintegerпринимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault writevalue_list=1, 2, 3
291bodymessageДата, уходящая в Vault
373map_examplemap
374json_example
diff --git a/generated/prod/docs/flask.md b/generated/prod/docs/flask.md deleted file mode 100644 index fc5aa48..0000000 --- a/generated/prod/docs/flask.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/flask_example.md b/generated/prod/docs/flask_example.md deleted file mode 100644 index de97f0c..0000000 --- a/generated/prod/docs/flask_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Copy-ready manifest (`flask_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_flask" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 300 # Квота ядра пода (milicores) - resource_memory = 256 # Квота памяти пода (MBytes) - resource_instances = 1 # Количество узлов - git_path = "https://github.com/Foxyhhd/Baldurs-Gate-test.git" # Путь до Git, который будет webroot для сайта - json_env = { "param": "value" } # Массив переменных, будут переданы в env приложения -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_flask.baza.state_params["имя_ключа"] -nubes_flask.baza.state_out["имя_ключа"] -nubes_flask.baza.state_params_flat["имя_ключа"] -nubes_flask.baza.state_out_flat["имя_ключа"] -nubes_flask.baza.vault_secrets["имя_ключа"] -nubes_flask.baza.vault_url -nubes_flask.baza.vault_user_path -nubes_flask.baza.vault_fields -``` diff --git a/generated/prod/docs/flask_ops.md b/generated/prod/docs/flask_ops.md deleted file mode 100644 index 0682476..0000000 --- a/generated/prod/docs/flask_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](flask_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](flask_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/flask_outputs.md b/generated/prod/docs/flask_outputs.md deleted file mode 100644 index a88f00a..0000000 --- a/generated/prod/docs/flask_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/flask_params.md b/generated/prod/docs/flask_params.md deleted file mode 100644 index 608ce56..0000000 --- a/generated/prod/docs/flask_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Parameters - -- [Create params](flask_params_create.md) -- [Modify params](flask_params_modify.md) diff --git a/generated/prod/docs/flask_params_create.md b/generated/prod/docs/flask_params_create.md deleted file mode 100644 index f063ce2..0000000 --- a/generated/prod/docs/flask_params_create.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
249resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
255health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
248domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
250resource_cpuinteger300Квота ядра пода (milicores)minvalue=100; maxvalue=4000
251resource_memoryinteger256Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
252resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
253git_pathstringhttps://github.com/Foxyhhd/Baldurs-Gate-test.gitПуть до Git, который будет webroot для сайта
254json_envstring{ &quot;param&quot;: &quot;value&quot; }Массив переменных, будут переданы в env приложения
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/flask_params_modify.md b/generated/prod/docs/flask_params_modify.md deleted file mode 100644 index 75a0716..0000000 --- a/generated/prod/docs/flask_params_modify.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Modify params - - - - - - - - - -
IDCodeTypeDescriptionConstraints
451resource_cpuintegerКвота ядра пода (milicores)minvalue=100; maxvalue=4000
452resource_memoryintegerКвота памяти пода (MBytes)minvalue=128; maxvalue=8192
453resource_instancesintegerКоличество узловminvalue=1; maxvalue=7
454git_pathПуть до Git, который будет webroot для сайта
455json_envjsonМассив переменных, будут переданы в env приложения
diff --git a/generated/prod/docs/gitea.md b/generated/prod/docs/gitea.md deleted file mode 100644 index b0fabf5..0000000 --- a/generated/prod/docs/gitea.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## MAN - -
-Развертывает сервис контроля версий Gitea
Зависит от сервиса postgresql который должен быть развернут заранее. -
diff --git a/generated/prod/docs/gitea_complex.md b/generated/prod/docs/gitea_complex.md deleted file mode 100644 index b67da5e..0000000 --- a/generated/prod/docs/gitea_complex.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## MAN - -
-Комплексная услуга из ["gittea", "postgres"] -
diff --git a/generated/prod/docs/gitea_complex_example.md b/generated/prod/docs/gitea_complex_example.md deleted file mode 100644 index e795ac0..0000000 --- a/generated/prod/docs/gitea_complex_example.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Copy-ready manifest (`gitea_complex_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_gitea_complex" "baza" { -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_gitea_complex.baza.state_params["имя_ключа"] -nubes_gitea_complex.baza.state_out["имя_ключа"] -nubes_gitea_complex.baza.state_params_flat["имя_ключа"] -nubes_gitea_complex.baza.state_out_flat["имя_ключа"] -nubes_gitea_complex.baza.vault_secrets["имя_ключа"] -nubes_gitea_complex.baza.vault_url -nubes_gitea_complex.baza.vault_user_path -nubes_gitea_complex.baza.vault_fields -``` diff --git a/generated/prod/docs/gitea_complex_ops.md b/generated/prod/docs/gitea_complex_ops.md deleted file mode 100644 index 4612ff3..0000000 --- a/generated/prod/docs/gitea_complex_ops.md +++ /dev/null @@ -1,10 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Operations - diff --git a/generated/prod/docs/gitea_complex_outputs.md b/generated/prod/docs/gitea_complex_outputs.md deleted file mode 100644 index f0593c8..0000000 --- a/generated/prod/docs/gitea_complex_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/gitea_complex_params.md b/generated/prod/docs/gitea_complex_params.md deleted file mode 100644 index ad58e7f..0000000 --- a/generated/prod/docs/gitea_complex_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Parameters - -- [Create params](gitea_complex_params_create.md) -- [Modify params](gitea_complex_params_modify.md) diff --git a/generated/prod/docs/gitea_complex_params_create.md b/generated/prod/docs/gitea_complex_params_create.md deleted file mode 100644 index 2f57dfd..0000000 --- a/generated/prod/docs/gitea_complex_params_create.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - -None. - -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/prod/docs/gitea_complex_params_modify.md b/generated/prod/docs/gitea_complex_params_modify.md deleted file mode 100644 index 472dee0..0000000 --- a/generated/prod/docs/gitea_complex_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/gitea_example.md b/generated/prod/docs/gitea_example.md deleted file mode 100644 index 3cea75b..0000000 --- a/generated/prod/docs/gitea_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Copy-ready manifest (`gitea_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_gitea" "baza" { - psql_uid = "TODO" # UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_gitea.baza.state_params["имя_ключа"] -nubes_gitea.baza.state_out["имя_ключа"] -nubes_gitea.baza.state_params_flat["имя_ключа"] -nubes_gitea.baza.state_out_flat["имя_ключа"] -nubes_gitea.baza.vault_secrets["имя_ключа"] -nubes_gitea.baza.vault_url -nubes_gitea.baza.vault_user_path -nubes_gitea.baza.vault_fields -``` diff --git a/generated/prod/docs/gitea_ops.md b/generated/prod/docs/gitea_ops.md deleted file mode 100644 index 0b22aac..0000000 --- a/generated/prod/docs/gitea_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](gitea_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](gitea_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/gitea_outputs.md b/generated/prod/docs/gitea_outputs.md deleted file mode 100644 index 3944814..0000000 --- a/generated/prod/docs/gitea_outputs.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` - diff --git a/generated/prod/docs/gitea_params.md b/generated/prod/docs/gitea_params.md deleted file mode 100644 index f0931ff..0000000 --- a/generated/prod/docs/gitea_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Parameters - -- [Create params](gitea_params_create.md) -- [Modify params](gitea_params_modify.md) diff --git a/generated/prod/docs/gitea_params_create.md b/generated/prod/docs/gitea_params_create.md deleted file mode 100644 index 378430a..0000000 --- a/generated/prod/docs/gitea_params_create.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
238psql_uiduuidUUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматическиref_svc_id=90
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
232resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=300; maxvalue=4000
233resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=256; maxvalue=8192
234resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
235resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
237domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/gitea_params_modify.md b/generated/prod/docs/gitea_params_modify.md deleted file mode 100644 index f584096..0000000 --- a/generated/prod/docs/gitea_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
259resource_cpuintegerКвота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=500; maxvalue=4000
260resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=256; maxvalue=8192
261resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
262resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
diff --git a/generated/prod/docs/harbor.md b/generated/prod/docs/harbor.md deleted file mode 100644 index c0cad0a..0000000 --- a/generated/prod/docs/harbor.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## MAN - -
-Расширенный реестр для управления Docker-образами с enterprise-функциями безопасности, репликации и контроля доступа.
Container Registry позволяет хранить, развертывать и управлять Docker-образами контейнеров в инфраструктуре NGcloud.
Сервис можно использовать в процессе разработки контейнеров. Например, вы можете настроить систему автоматизации на работу с реестром в Container Registry в рамках процесса непрерывной интеграции. Контейнеры идеально подходят для запуска небольших, независимых и легко изменяемых сервисов.
Чтобы начать работу, создайте реестр и загрузите в него Docker-образ
Авторизация: keycloak -
diff --git a/generated/prod/docs/harbor_example.md b/generated/prod/docs/harbor_example.md deleted file mode 100644 index 5220c95..0000000 --- a/generated/prod/docs/harbor_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Copy-ready manifest (`harbor_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_harbor" "baza" { - resource_realm = "TODO" # Платформа для развертывания - s3_uid = "TODO" # UUID экземпляра услуги S3 - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - emails = "testuser1" # Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел - resource_cpu = 100 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 200 # Квота памяти пода (Указывается в Megabytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_harbor.baza.state_params["имя_ключа"] -nubes_harbor.baza.state_out["имя_ключа"] -nubes_harbor.baza.state_params_flat["имя_ключа"] -nubes_harbor.baza.state_out_flat["имя_ключа"] -nubes_harbor.baza.vault_secrets["имя_ключа"] -nubes_harbor.baza.vault_url -nubes_harbor.baza.vault_user_path -nubes_harbor.baza.vault_fields -``` diff --git a/generated/prod/docs/harbor_ops.md b/generated/prod/docs/harbor_ops.md deleted file mode 100644 index 9a06a19..0000000 --- a/generated/prod/docs/harbor_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](harbor_params_create.md) -- `delete` — DEV-Ветка удаления Harbor diff --git a/generated/prod/docs/harbor_outputs.md b/generated/prod/docs/harbor_outputs.md deleted file mode 100644 index 3422bbd..0000000 --- a/generated/prod/docs/harbor_outputs.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.k8sregistry"]` -- `state_out_flat["monitoring.k8sregistry.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` - diff --git a/generated/prod/docs/harbor_params.md b/generated/prod/docs/harbor_params.md deleted file mode 100644 index 6819254..0000000 --- a/generated/prod/docs/harbor_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Parameters - -- [Create params](harbor_params_create.md) -- [Modify params](harbor_params_modify.md) diff --git a/generated/prod/docs/harbor_params_create.md b/generated/prod/docs/harbor_params_create.md deleted file mode 100644 index d5f1c60..0000000 --- a/generated/prod/docs/harbor_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
110resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
231s3_uiduuidUUID экземпляра услуги S3ref_svc_id=12
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
16domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
17emailsstringtestuser1Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел
228resource_cpuinteger100Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
229resource_memoryinteger200Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
230resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
diff --git a/generated/prod/docs/harbor_params_modify.md b/generated/prod/docs/harbor_params_modify.md deleted file mode 100644 index 0960de7..0000000 --- a/generated/prod/docs/harbor_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/http.md b/generated/prod/docs/http.md deleted file mode 100644 index 68075b0..0000000 --- a/generated/prod/docs/http.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/http_example.md b/generated/prod/docs/http_example.md deleted file mode 100644 index 1c12225..0000000 --- a/generated/prod/docs/http_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Copy-ready manifest (`http_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_http" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 100 # Квота ядра пода (Указывается в mili) - resource_memory = 200 # Квота памяти пода (Указывается в Megabytes) - resource_instances = 1 # Количество узлов - registry_path = "nexus-sa.tst.nubes.ru/docker-nubes/jolt" # Путь до image, который будет установлен как deployment - json_env = {"param": "value"} # Массив переменных, будут переданы в env приложения -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_http.baza.state_params["имя_ключа"] -nubes_http.baza.state_out["имя_ключа"] -nubes_http.baza.state_params_flat["имя_ключа"] -nubes_http.baza.state_out_flat["имя_ключа"] -nubes_http.baza.vault_secrets["имя_ключа"] -nubes_http.baza.vault_url -nubes_http.baza.vault_user_path -nubes_http.baza.vault_fields -``` diff --git a/generated/prod/docs/http_ops.md b/generated/prod/docs/http_ops.md deleted file mode 100644 index 547defd..0000000 --- a/generated/prod/docs/http_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](http_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](http_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/prod/docs/http_outputs.md b/generated/prod/docs/http_outputs.md deleted file mode 100644 index 9baf737..0000000 --- a/generated/prod/docs/http_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/prod/docs/http_params.md b/generated/prod/docs/http_params.md deleted file mode 100644 index 07aa372..0000000 --- a/generated/prod/docs/http_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Parameters - -- [Create params](http_params_create.md) -- [Modify params](http_params_modify.md) diff --git a/generated/prod/docs/http_params_create.md b/generated/prod/docs/http_params_create.md deleted file mode 100644 index aa7d336..0000000 --- a/generated/prod/docs/http_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
216resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
212domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
213resource_cpuinteger100Квота ядра пода (Указывается в mili)minvalue=100; maxvalue=4000
214resource_memoryinteger200Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
215resource_instancesinteger1Количество реплик приложения. Трафик будет распределяться между подами в режиме Round-Robinminvalue=1; maxvalue=7
217registry_pathstringnexus-sa.tst.nubes.ru/docker-nubes/joltПуть до image, который будет установлен как deployment
241json_envjson{&quot;param&quot;: &quot;value&quot;}Массив переменных, будут переданы в env приложения
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/http_params_modify.md b/generated/prod/docs/http_params_modify.md deleted file mode 100644 index 75a69ec..0000000 --- a/generated/prod/docs/http_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
218resource_cpuintegerminvalue=100; maxvalue=4000
219resource_memoryintegerminvalue=128; maxvalue=8192
220resource_instancesintegerКоличество узловminvalue=1; maxvalue=7
diff --git a/generated/prod/docs/k8s_sthutrval_cluster.md b/generated/prod/docs/k8s_sthutrval_cluster.md deleted file mode 100644 index b3b0523..0000000 --- a/generated/prod/docs/k8s_sthutrval_cluster.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## MAN - -
-Перед разворачиванием убедиться, что в облаке есть 2 свободных невыделенных IP в пуле -
diff --git a/generated/prod/docs/k8s_sthutrval_cluster_example.md b/generated/prod/docs/k8s_sthutrval_cluster_example.md deleted file mode 100644 index 2b8b2ea..0000000 --- a/generated/prod/docs/k8s_sthutrval_cluster_example.md +++ /dev/null @@ -1,58 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Copy-ready manifest (`k8s_sthutrval_cluster_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_k8s_sthutrval_cluster" "baza" { - nsxt_uid = "TODO" # InstanceUid nsxt. Nsxt должен быть создан - control_plane_sizing_policy = "TODO" # Настройка Control Plane. CPU (шт) / MEM (gb). Наверное, должна подтягиваться из свойств ресурсной платформы - workers_sizing_policy = "TODO" # Настройка workers. CPU (шт) / MEM (gb) - vdc_uid = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - cluster_name = "example1" # Наименование кластера Kubernetes. Имя будет использоваться в fqdn (svc.$CLUSTER_NAME) - control_plane_sizing_disk = 30 # Настройка Control Plane. Disk (Gb) - control_plane_count = 1 - workers_sizing_disk = 40 # Настройка workers. Disk (Gb) - workers_count = 2 # Настройка workers. Кол-во нод - app_version = 2.12.1 # Версия Штурвал (не является версией Kubernetes) - need_external_address_api = true # Выделяет внешний IP для доступа к kubernetes API. Пока нельзя выставить false - access_ip_list_api = [] # Access IP List для подключения к Kubernetes API. Указывается массив. Если передан пустой массив, доступ выделяется всем - need_external_address_ingress = true # Выделяет внешний IP для доступа к Ingress - access_ip_list_ingress = [] # Access IP List для подключения к Ingress. Указывается массив. Если передан пустой массив, доступ выделяется всем -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_k8s_sthutrval_cluster.baza.state_params["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_out["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_params_flat["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_out_flat["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.vault_secrets["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.vault_url -nubes_k8s_sthutrval_cluster.baza.vault_user_path -nubes_k8s_sthutrval_cluster.baza.vault_fields -``` diff --git a/generated/prod/docs/k8s_sthutrval_cluster_ops.md b/generated/prod/docs/k8s_sthutrval_cluster_ops.md deleted file mode 100644 index afb94fd..0000000 --- a/generated/prod/docs/k8s_sthutrval_cluster_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](k8s_sthutrval_cluster_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](k8s_sthutrval_cluster_params_modify.md) -- `reconcile` -- `resume` -- `suspend` -- `update_secrets` diff --git a/generated/prod/docs/k8s_sthutrval_cluster_outputs.md b/generated/prod/docs/k8s_sthutrval_cluster_outputs.md deleted file mode 100644 index 065be3b..0000000 --- a/generated/prod/docs/k8s_sthutrval_cluster_outputs.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["ingressAddress"]` -- `state_out_flat["kubernetesApiAddress"]` - -### `vault_secrets` ключи - -- `vault_secrets["kubernetesAdminConfigB64"]` - diff --git a/generated/prod/docs/k8s_sthutrval_cluster_params.md b/generated/prod/docs/k8s_sthutrval_cluster_params.md deleted file mode 100644 index 641f838..0000000 --- a/generated/prod/docs/k8s_sthutrval_cluster_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Parameters - -- [Create params](k8s_sthutrval_cluster_params_create.md) -- [Modify params](k8s_sthutrval_cluster_params_modify.md) diff --git a/generated/prod/docs/k8s_sthutrval_cluster_params_create.md b/generated/prod/docs/k8s_sthutrval_cluster_params_create.md deleted file mode 100644 index 6e21a3c..0000000 --- a/generated/prod/docs/k8s_sthutrval_cluster_params_create.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
344nsxt_uiduuidInstanceUid nsxt. Nsxt должен быть созданref_svc_id=22
346control_plane_sizing_policystringНастройка Control Plane. CPU (шт) / MEM (gb).
Наверное, должна подтягиваться из свойств ресурсной платформы
349workers_sizing_policystringНастройка workers. CPU (шт) / MEM (gb)
747vdc_uiduuidref_svc_id=21
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
345cluster_namestringexample1Наименование кластера Kubernetes. Имя будет использоваться в fqdn (svc.$CLUSTER_NAME)regex=(?=^.{1,63}$)^[a-z0-9]([a-z0-9-]*[a-z0-9])?$; unique_scope=provider
347control_plane_sizing_diskinteger30Настройка Control Plane. Disk (Gb)minvalue=20; maxvalue=999
348control_plane_countinteger1minvalue=1; maxvalue=9
350workers_sizing_diskinteger40Настройка workers. Disk (Gb)minvalue=20; maxvalue=999
351workers_countinteger2Настройка workers. Кол-во нодminvalue=1; maxvalue=99
352app_versionstring2.12.1Версия Штурвал (не является версией Kubernetes)value_list=2.12.1, 2.11.0
353need_external_address_apibooleantrueВыделяет внешний IP для доступа к kubernetes API. Пока нельзя выставить falsevalue_list=true
354access_ip_list_apijson[]Access IP List для подключения к Kubernetes API. Указывается массив. Если передан пустой массив, доступ выделяется всем
355need_external_address_ingressbooleantrueВыделяет внешний IP для доступа к Ingressvalue_list=true
356access_ip_list_ingressjson[]Access IP List для подключения к Ingress. Указывается массив. Если передан пустой массив, доступ выделяется всем
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/k8s_sthutrval_cluster_params_modify.md b/generated/prod/docs/k8s_sthutrval_cluster_params_modify.md deleted file mode 100644 index 21776a5..0000000 --- a/generated/prod/docs/k8s_sthutrval_cluster_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
362control_plane_countintegerКол-во нод Control Planeminvalue=1; maxvalue=9
363workers_countintegerКол-во нод Workersminvalue=1; maxvalue=99
364access_ip_list_apijsonAccess IP List для подключения к Kubernetes API. Указывается массив. Если передан пустой массив, доступ выделяется всем
365access_ip_list_ingressjsonAccess IP List для подключения к Ingress. Указывается массив. Если передан пустой массив, доступ выделяется всем
563app_versionstringВерсия Штурвал (не является версией Kubernetes)
Понижать версию нельзя
Обновиться на несколько минорных нельзя
Невозможно перепрыгнуть не с последней минорной на мажорную
Можно обновиться на несколько патчей
value_list=2.11.0, 2.12.1
637control_plane_sizing_diskinteger
638workers_sizing_diskinteger
diff --git a/generated/prod/docs/k8s_ziti_controller.md b/generated/prod/docs/k8s_ziti_controller.md deleted file mode 100644 index 5c8b8f3..0000000 --- a/generated/prod/docs/k8s_ziti_controller.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/k8s_ziti_controller_example.md b/generated/prod/docs/k8s_ziti_controller_example.md deleted file mode 100644 index 7643188..0000000 --- a/generated/prod/docs/k8s_ziti_controller_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Copy-ready manifest (`k8s_ziti_controller_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_k8s_ziti_controller" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 300 # Квота ядра пода (milicores) - resource_memory = 512 # Квота памяти пода (MBytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_k8s_ziti_controller.baza.state_params["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_out["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_params_flat["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_out_flat["имя_ключа"] -nubes_k8s_ziti_controller.baza.vault_secrets["имя_ключа"] -nubes_k8s_ziti_controller.baza.vault_url -nubes_k8s_ziti_controller.baza.vault_user_path -nubes_k8s_ziti_controller.baza.vault_fields -``` diff --git a/generated/prod/docs/k8s_ziti_controller_ops.md b/generated/prod/docs/k8s_ziti_controller_ops.md deleted file mode 100644 index 8da7234..0000000 --- a/generated/prod/docs/k8s_ziti_controller_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](k8s_ziti_controller_params_create.md) -- `delete` diff --git a/generated/prod/docs/k8s_ziti_controller_outputs.md b/generated/prod/docs/k8s_ziti_controller_outputs.md deleted file mode 100644 index 6fc1fdd..0000000 --- a/generated/prod/docs/k8s_ziti_controller_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/k8s_ziti_controller_params.md b/generated/prod/docs/k8s_ziti_controller_params.md deleted file mode 100644 index 343d93e..0000000 --- a/generated/prod/docs/k8s_ziti_controller_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Parameters - -- [Create params](k8s_ziti_controller_params_create.md) -- [Modify params](k8s_ziti_controller_params_modify.md) diff --git a/generated/prod/docs/k8s_ziti_controller_params_create.md b/generated/prod/docs/k8s_ziti_controller_params_create.md deleted file mode 100644 index dac54da..0000000 --- a/generated/prod/docs/k8s_ziti_controller_params_create.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
298resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
294resource_cpuinteger300Квота ядра пода (milicores)minvalue=100; maxvalue=4000
295resource_memoryinteger512Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
296resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
297resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
299domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
diff --git a/generated/prod/docs/k8s_ziti_controller_params_modify.md b/generated/prod/docs/k8s_ziti_controller_params_modify.md deleted file mode 100644 index 1998e6a..0000000 --- a/generated/prod/docs/k8s_ziti_controller_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/kafka.md b/generated/prod/docs/kafka.md deleted file mode 100644 index 1c4e5e5..0000000 --- a/generated/prod/docs/kafka.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## MAN - -
-# Инструкция по развертыванию Apache Kafka через платформу

---
## 1. Общая информация
Брокер сообщений Apache Kafka — это отказоустойчивая распределённая платформа для обмена сообщениями и потоковой обработки данных в реальном времени.
Позволяет надёжно передавать события между сервисами и системами, интегрироваться с внешними решениями и использовать как внутренние, так и защищённые TLS-подключения. Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание кластера
- **delete** — Удаление кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера

- **create_topic** — Создание топика
- **modify_topic** — Модификация топика
- **delete_topic** — Удаление топика

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя


---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса Kafka:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: ` k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество узлов (брокеров) в кластере Kafka

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore ) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных в гигабайтах. Пример: `20`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`

---
## 4. Выходные параметры
После успешного развертывания ресурса Kafka платформа возвращает ряд параметров.
Ключевым из них является:

**internalConnect**
Это внутренний эндпоинт, который используется для подключения к кластеру Kafka из других сервисов, развернутых внутри той же сети.
Эндпоинт предоставляет доступ к брокерам Kafka по внутренним портам, указанным в конфигурации слушателей.

**externalConnect**
Это внешний эндпоинт (fqdn), который используется для подключения к кластеру Kafka. Для подключения используеться 9093 порт.

Для подключения используются следующие порты:

* 9092 — внутренний нешифрованный доступ (plain).
* 9093 — внутренний и внешний доступ по TLS, с обязательной TLS-аутентификацией.

---
## 5. Дополнительная информация
Для создания топиков, пользователей и управления ими, а также для интеграции с кластерами Kafka используйте соответствующие сервисы и раздел "Облачные сервисы".
--- -
diff --git a/generated/prod/docs/kafka_example.md b/generated/prod/docs/kafka_example.md deleted file mode 100644 index ec23b8d..0000000 --- a/generated/prod/docs/kafka_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Copy-ready manifest (`kafka_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_kafka" "baza" { - resource_instances = 1 # Пример: `2` - resource_memory = 1 # Пример: `2048` - resource_cpu = 1 # Пример: `2000` - resource_disk = 1 # Пример: `20` - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - need_external_address_master = false # Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_kafka.baza.state_params["имя_ключа"] -nubes_kafka.baza.state_out["имя_ключа"] -nubes_kafka.baza.state_params_flat["имя_ключа"] -nubes_kafka.baza.state_out_flat["имя_ключа"] -nubes_kafka.baza.vault_secrets["имя_ключа"] -nubes_kafka.baza.vault_url -nubes_kafka.baza.vault_user_path -nubes_kafka.baza.vault_fields -``` diff --git a/generated/prod/docs/kafka_ops.md b/generated/prod/docs/kafka_ops.md deleted file mode 100644 index 21e6e30..0000000 --- a/generated/prod/docs/kafka_ops.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](kafka_params_create.md) -- `create_topic` — Создание кластера. Параметры: [Create params](kafka_params_create.md) -- `create_user` — Создание кластера. Параметры: [Create params](kafka_params_create.md) -- `delete` -- `delete_topic` -- `delete_user` — # Инструкция по управлению пользователями Apache Kafka. --- ## 1. Общая информация Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру. Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам. Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka. --- ## Доступные операции - **create_user** — Создание пользователя - **modify_user** — Модификация пользователя - **delete_user** — Удаление пользователя --- ## 2. Параметры создания пользователя Ниже перечислены параметры, которые необходимо указать при создании нового пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 3. Параметры модификации пользователя Ниже перечислены параметры, которые необходимо указать при модификации пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 4. Параметры удалении пользователя Ниже перечислены параметры, которые необходимо указать при удалении пользователя: * **Имя пользователя** Имя удаляемого пользователя. Пример: `username-admin` ## 5. Выходные параметры После успешного создания пользователя платформа возвращает параметры, необходимые для подключения: * **ca.crt** Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении. Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **ca.p12** PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.p12 ``` * **ca.password** Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно. * **user.crt** Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka. Используется совместно с приватным ключом `user.key` для аутентификации. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **user.key** Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.key ``` * **user.p12** PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo "<содержание поля>" | base64 -d > <название>.p12 ``` * **user.password** Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно. Эти параметры используются для настройки TLS-подключения. --- ## 6. Пример конфигурации клиента внутри кластера Пример пода: ```yaml apiVersion: v1 kind: Pod metadata: name: kafka-4 spec: volumes: - name: work emptyDir: {} containers: - name: kcat image: quay.io/strimzi/kafka:latest-kafka-4.0.0 command: ["sleep", "5600"] volumeMounts: - name: work mountPath: /work restartPolicy: Never ``` Создаём под и сохраняем сертификаты: ```bash kubectl cp user.p12 kafka-4:/work/ kubectl cp ca.p12 kafka-4:/work/ ``` Создаём файлы конфигурации: ```bash cat > /work/user-read.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` ```bash cat > /work/user-write.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user-write.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` Листинг доступных топиков: ```bash /opt/kafka/bin/kafka-topics.sh \ --bootstrap-server kafkak8s-bootstrap-external:9093 \ --command-config /work/user-read.properties \ --list ``` Запись сообщений: ```bash /opt/kafka/bin/kafka-console-producer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --producer.config /work/user-write.properties ``` Чтение сообщений: ```bash /opt/kafka/bin/kafka-console-consumer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --from-beginning \ --group \ --consumer.config /work/user-read.properties \ --max-messages 50 ``` --- ## 7. Пример внешнего подключения с использованием **kcat** **Листинг топиков** ```bash kcat -b :9093 \ -L \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` **Запись сообщения** ```bash echo "hello from kcat" | kcat -P \ -b :9093 \ -t write-test \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-write.crt \ -X ssl.key.location=./user-write.key \ -X ssl.endpoint.identification.algorithm=none ``` **Чтение сообщений** ```bash kcat -C \ -b :9093 \ -t write-test \ -o beginning \ -q \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` --- ## 9. Рекомендации * Минимизируйте набор разрешённых операций для повышения безопасности. * Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов. * Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**. * После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам. --- -- `modify` — Изменение кластера. Параметры: [Modify params](kafka_params_modify.md) -- `modify_topic` — Изменение кластера. Параметры: [Modify params](kafka_params_modify.md) -- `modify_user` — Изменение кластера. Параметры: [Modify params](kafka_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/kafka_outputs.md b/generated/prod/docs/kafka_outputs.md deleted file mode 100644 index 7a36056..0000000 --- a/generated/prod/docs/kafka_outputs.md +++ /dev/null @@ -1,54 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.bootstrap"]` -- `state_out_flat["externalConnect.bootstrap.fqdn"]` -- `state_out_flat["externalConnect.bootstrap.ip"]` -- `state_out_flat["externalConnect.bootstrap.isExternal"]` -- `state_out_flat["externalConnect.bootstrap.uuid"]` -- `state_out_flat["internalConnect"]` -- `state_out_flat["kafkaTopics"]` -- `state_out_flat["kafkaTopics.test-events"]` -- `state_out_flat["kafkaTopics.test-events.partitions"]` -- `state_out_flat["kafkaTopics.test-events.replicas"]` -- `state_out_flat["kafkaUsers"]` -- `state_out_flat["kafkaUsers.usertest"]` -- `state_out_flat["kafkaUsers.usertest.accessHosts"]` -- `state_out_flat["kafkaUsers.usertest.group"]` -- `state_out_flat["kafkaUsers.usertest.nameTopic"]` -- `state_out_flat["kafkaUsers.usertest.operations"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["users"]` - diff --git a/generated/prod/docs/kafka_params.md b/generated/prod/docs/kafka_params.md deleted file mode 100644 index 25cb573..0000000 --- a/generated/prod/docs/kafka_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Parameters - -- [Create params](kafka_params_create.md) -- [Modify params](kafka_params_modify.md) diff --git a/generated/prod/docs/kafka_params_create.md b/generated/prod/docs/kafka_params_create.md deleted file mode 100644 index 1a43a4e..0000000 --- a/generated/prod/docs/kafka_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
461resource_instancesintegerПример: `2`minvalue=1; value_list=1, 2, 3, 4, 5
462resource_memoryintegerПример: `2048`minvalue=1000
463resource_cpuintegerПример: `2000`minvalue=1000
464resource_diskintegerПример: `20`
466ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
469resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
465need_external_address_masterbooleanfalseФлаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`value_list=false, true
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/kafka_params_modify.md b/generated/prod/docs/kafka_params_modify.md deleted file mode 100644 index e6ff431..0000000 --- a/generated/prod/docs/kafka_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
501resource_instancesintegerПример: `2`value_list=1, 2, 3, 4, 5
502resource_memoryintegerПример: `2048`minvalue=1000
503resource_cpuПример: `2000`minvalue=1000
504resource_diskintegerПример: `20`
505need_external_address_masterbooleanФлаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`value_list=false, true
506ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
diff --git a/generated/prod/docs/lucee.md b/generated/prod/docs/lucee.md deleted file mode 100644 index ca3542d..0000000 --- a/generated/prod/docs/lucee.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/lucee_example.md b/generated/prod/docs/lucee_example.md deleted file mode 100644 index 5f5ea22..0000000 --- a/generated/prod/docs/lucee_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Copy-ready manifest (`lucee_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_lucee" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - git_path = "https://github.com/xahys/testlucee" # Путь до Git, который будет webroot для сайта - json_env = { "param": "value" } # Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения. - resource_cpu = 300 # Квота ядра пода (milicores) - resource_memory = 512 # Квота памяти пода (MBytes) - resource_instances = 1 # Количество узлов - app_version = 5.4 # Версия Lucee -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_lucee.baza.state_params["имя_ключа"] -nubes_lucee.baza.state_out["имя_ключа"] -nubes_lucee.baza.state_params_flat["имя_ключа"] -nubes_lucee.baza.state_out_flat["имя_ключа"] -nubes_lucee.baza.vault_secrets["имя_ключа"] -nubes_lucee.baza.vault_url -nubes_lucee.baza.vault_user_path -nubes_lucee.baza.vault_fields -``` diff --git a/generated/prod/docs/lucee_ops.md b/generated/prod/docs/lucee_ops.md deleted file mode 100644 index 3294ee8..0000000 --- a/generated/prod/docs/lucee_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](lucee_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](lucee_params_modify.md) -- `redeploy` -- `restart` -- `resume` -- `suspend` diff --git a/generated/prod/docs/lucee_outputs.md b/generated/prod/docs/lucee_outputs.md deleted file mode 100644 index 838f21d..0000000 --- a/generated/prod/docs/lucee_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/prod/docs/lucee_params.md b/generated/prod/docs/lucee_params.md deleted file mode 100644 index 730e3b2..0000000 --- a/generated/prod/docs/lucee_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Parameters - -- [Create params](lucee_params_create.md) -- [Modify params](lucee_params_modify.md) diff --git a/generated/prod/docs/lucee_params_create.md b/generated/prod/docs/lucee_params_create.md deleted file mode 100644 index f63e87a..0000000 --- a/generated/prod/docs/lucee_params_create.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
108resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
132health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
103domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
104git_pathstringhttps://github.com/xahys/testluceeПуть до Git, который будет webroot для сайта
105json_envjson{ "param": "value" }Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения.maxlength=2048
106resource_cpuinteger300Квота ядра пода (milicores)minvalue=100; maxvalue=4000
107resource_memoryinteger512Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
139resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
263app_versionstring5.4Версия Luceeregex=^\d+(\.\d+){1,2}(-[a-zA-Z0-9\.]+)?$; value_list=5.4, 6.0
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/lucee_params_modify.md b/generated/prod/docs/lucee_params_modify.md deleted file mode 100644 index 087ab68..0000000 --- a/generated/prod/docs/lucee_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
133git_pathstringПуть до Git, который будет webroot для сайта
134health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код.
135json_envjsonМассив переменных, будут переданы в env приложенияmaxlength=2048
136resource_cpuintegerКвота ядра пода (Указывается в mili)minvalue=100; maxvalue=4000
137resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
138resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
264app_versionstringregex=^\d+(\.\d+){1,2}(-[a-zA-Z0-9\.]+)?$; value_list=5.4, 6.0
diff --git a/generated/prod/docs/mariadb.md b/generated/prod/docs/mariadb.md deleted file mode 100644 index 9161094..0000000 --- a/generated/prod/docs/mariadb.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## MAN - -
-Mariadb кластер. Ресурсная платформа: k8s. Автоматизация: k8s operator.
Автоматическое резервное копирование, ручное восстановление. -
diff --git a/generated/prod/docs/mariadb_example.md b/generated/prod/docs/mariadb_example.md deleted file mode 100644 index f5b8378..0000000 --- a/generated/prod/docs/mariadb_example.md +++ /dev/null @@ -1,57 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Copy-ready manifest (`mariadb_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_mariadb" "baza" { - resource_realm = "TODO" # Платформа для развертывания - s3_uid = "TODO" # Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Квота ядра пода (milicores) - resource_memory = 1024 # Квота памяти пода (MBytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - need_external_address_master = false # Выделяет внешний (белый) IP для доступа к master - ext_backup_schedule = "0 * * * *" # Не обязательный. Время запуска бекапа - app_version = 9.4.0 # Версия MySQL - auto_scale = false # Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги - auto_scale_percentage = 10 # Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема - auto_scale_tech_window = 0 # Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) - auto_scale_quota_gb = 1 # Квота для autoScale -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_mariadb.baza.state_params["имя_ключа"] -nubes_mariadb.baza.state_out["имя_ключа"] -nubes_mariadb.baza.state_params_flat["имя_ключа"] -nubes_mariadb.baza.state_out_flat["имя_ключа"] -nubes_mariadb.baza.vault_secrets["имя_ключа"] -nubes_mariadb.baza.vault_url -nubes_mariadb.baza.vault_user_path -nubes_mariadb.baza.vault_fields -``` diff --git a/generated/prod/docs/mariadb_ops.md b/generated/prod/docs/mariadb_ops.md deleted file mode 100644 index 32042ca..0000000 --- a/generated/prod/docs/mariadb_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](mariadb_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](mariadb_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/mariadb_outputs.md b/generated/prod/docs/mariadb_outputs.md deleted file mode 100644 index 38f0606..0000000 --- a/generated/prod/docs/mariadb_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/mariadb_params.md b/generated/prod/docs/mariadb_params.md deleted file mode 100644 index 1d0477b..0000000 --- a/generated/prod/docs/mariadb_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Parameters - -- [Create params](mariadb_params_create.md) -- [Modify params](mariadb_params_modify.md) diff --git a/generated/prod/docs/mariadb_params_create.md b/generated/prod/docs/mariadb_params_create.md deleted file mode 100644 index 4f6f74c..0000000 --- a/generated/prod/docs/mariadb_params_create.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
422resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
429ip_space_name_masterstringИмя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster
459s3_uiduuidЭкземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательноref_svc_id=12
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
424resource_cpuinteger500Квота ядра пода (milicores)minvalue=500; maxvalue=4000
425resource_memoryinteger1024Квота памяти пода (MBytes)minvalue=1024; maxvalue=8192
426resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
427resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
428need_external_address_masterbooleanfalseВыделяет внешний (белый) IP для доступа к mastervalue_list=false, true
430ext_backup_schedulestring0 * * * *Не обязательный. Время запуска бекапаregex=^(\*|(\d+|\*\/\d+|\d+(,\d+)*))\s\*\s\*\s\*\s\*$
431app_versionstring9.4.0Версия MySQLvalue_list=8.4.0, 9.4.0
432auto_scalebooleanfalseВключает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услугиvalue_list=false, true
433auto_scale_percentageinteger10Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объемаvalue_list=10, 15, 20
434auto_scale_tech_windowinteger0Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23)value_list=0, 5, 12, 23
435auto_scale_quota_gbinteger1Квота для autoScale
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/mariadb_params_modify.md b/generated/prod/docs/mariadb_params_modify.md deleted file mode 100644 index c17f0d8..0000000 --- a/generated/prod/docs/mariadb_params_modify.md +++ /dev/null @@ -1,25 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Modify params - - - - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
436resource_cpuinteger
437resource_memoryinteger
438resource_instancesinteger
439resource_diskinteger
440need_external_address_masterbooleanvalue_list=false, true
441ip_space_name_master
442ext_backup_schedulestring
443auto_scalebooleanvalue_list=false, true
444auto_scale_percentageinteger
445auto_scale_tech_windowinteger
446auto_scale_quota_gbinteger
diff --git a/generated/prod/docs/mongodb.md b/generated/prod/docs/mongodb.md deleted file mode 100644 index fb0375a..0000000 --- a/generated/prod/docs/mongodb.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## MAN - -
-# Инструкция по развертыванию MongoDB через платформу

## 1. Общая информация

MongoDB — документоориентированная распределённая база данных, обеспечивающая высокую доступность, горизонтальное масштабирование и гибкую модель хранения.

### Доступные операции с кластером

* **create** — создание кластера
* **delete** — удаление кластера
* **suspend** — остановка кластера
* **resume** — запуск кластера

### Доступные операции с пользователями

* **create_user** — создание пользователя
* **modify_user** — модификация пользователя
* **delete_user** — удаление пользователя

---

## 2. Параметры развертывания кластера

Эти параметры необходимо указать при создании кластера.

### Платформа для развертывания

Среда, в которой будет развернут кластер. Выбирается из предложенного списка.

### Количество узлов

Оптимально выбирать нечётное количество узлов в кластере MongoDB, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность кластера даже при отказе одной из нод.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных в гигабайтах.
Пример: `20`

### Выделение внешнего IP для доступа к master

Флаг, определяющий необходимость выделения внешнего IP.
Допустимые значения: `true` или `false`

### Имя ipSpace для публикации внешнего IP

Указывается только если включено выделение внешнего IP.
Пример: `internet-no-antiddos-v1`

---

## 3. Параметры создания пользователя

### Имя пользователя

Указывается имя пользователя (любой регистр).
Пример: `readApp`

### Имя базы данных

Название базы, в которой будет создан пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read** — доступ только на чтение
* **readWrite** — чтение и изменение данных
* **dbOwner** — полный контроль над базой данных

---

## 4. Параметры модификации пользователя

### Имя пользователя

Необходимо выбрать существующего пользователя.
Если список пуст, требуется предварительно создать пользователя.

### Имя базы данных

База данных, к которой относится пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read**
* **readWrite**
* **dbOwner**

---

## 5. Параметры удаления пользователя

### Имя пользователя

Выберите пользователя из списка для удаления.

---

## 6. Выходные параметры

После успешного развертывания кластера платформа возвращает ключевые параметры.

### internalConnect

Внутренний эндпоинт для подключения к кластеру из сервисов, работающих в той же сети.
Используется для внутренних интеграций и системных сервисов.

### externalConnect

Внешний FQDN для подключения к кластеру извне.
Порт подключения — **27017**.

---

## 7. Пример подключения

Перед подключением необходимо установить **mongosh**.

Команда подключения к базе данных:

```
mongosh "mongodb://<username>:<password>@<endpoint_db>:27017/<dbName>"
```

Где:

* `<username>` — имя пользователя
* `<password>` — пароль
* `<endpoint_db>` — internalConnect или externalConnect
* `<dbName>` — имя базы данных

## 8. Дополнительная информация

Сейчас соединение с базой работает без шифрования, и доступ к кластеру осуществляется только по логину и паролю. -
diff --git a/generated/prod/docs/mongodb_example.md b/generated/prod/docs/mongodb_example.md deleted file mode 100644 index c799e4f..0000000 --- a/generated/prod/docs/mongodb_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Copy-ready manifest (`mongodb_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_mongodb" "baza" { - resource_instances = 1 # Пример: `2` - resource_memory = 1 # Пример: `2048` - resource_cpu = 1 # Пример: `1000` - resource_disk = 1 # Пример: `20` - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - need_external_address_master = false # Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_mongodb.baza.state_params["имя_ключа"] -nubes_mongodb.baza.state_out["имя_ключа"] -nubes_mongodb.baza.state_params_flat["имя_ключа"] -nubes_mongodb.baza.state_out_flat["имя_ключа"] -nubes_mongodb.baza.vault_secrets["имя_ключа"] -nubes_mongodb.baza.vault_url -nubes_mongodb.baza.vault_user_path -nubes_mongodb.baza.vault_fields -``` diff --git a/generated/prod/docs/mongodb_ops.md b/generated/prod/docs/mongodb_ops.md deleted file mode 100644 index b933306..0000000 --- a/generated/prod/docs/mongodb_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](mongodb_params_create.md) -- `create_user` — Создание кластера. Параметры: [Create params](mongodb_params_create.md) -- `delete` -- `delete_user` -- `modify_user` — Изменение кластера. Параметры: [Modify params](mongodb_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/mongodb_outputs.md b/generated/prod/docs/mongodb_outputs.md deleted file mode 100644 index 2a6b2dc..0000000 --- a/generated/prod/docs/mongodb_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["internalConnect"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/prod/docs/mongodb_params.md b/generated/prod/docs/mongodb_params.md deleted file mode 100644 index b595ec1..0000000 --- a/generated/prod/docs/mongodb_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Parameters - -- [Create params](mongodb_params_create.md) -- [Modify params](mongodb_params_modify.md) diff --git a/generated/prod/docs/mongodb_params_create.md b/generated/prod/docs/mongodb_params_create.md deleted file mode 100644 index ce9ff39..0000000 --- a/generated/prod/docs/mongodb_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
487resource_instancesintegerПример: `2`minvalue=1; maxvalue=7
588resource_memoryintegerПример: `2048`minvalue=1000
589resource_cpuintegerПример: `1000`
590resource_diskintegerПример: `20`
595resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
646ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
645need_external_address_masterstringfalseФлаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`value_list=false, true
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/mongodb_params_modify.md b/generated/prod/docs/mongodb_params_modify.md deleted file mode 100644 index 369e9ef..0000000 --- a/generated/prod/docs/mongodb_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/nextcloud.md b/generated/prod/docs/nextcloud.md deleted file mode 100644 index a494623..0000000 --- a/generated/prod/docs/nextcloud.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## MAN - -
-Ресурсная платформа: k8s. Автоматизация: helm chart -
diff --git a/generated/prod/docs/nextcloud_example.md b/generated/prod/docs/nextcloud_example.md deleted file mode 100644 index 50ada44..0000000 --- a/generated/prod/docs/nextcloud_example.md +++ /dev/null @@ -1,53 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Copy-ready manifest (`nextcloud_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_nextcloud" "baza" { - psql_uid = "TODO" - redis_uid = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 1000 # Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili - resource_memory = 1024 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 2 # Квота диска (Указывается в GIGAbytes) Диск не может быть меньше 2G (!) - document_server = "collabora" # Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен Размер пода collabora: 1.8 ядра. 2Gi ОЗУ - resource_instances = 1 # Количество узлов Не может пока быть больше одного, так как нужны SC под RWMany - app_version = 32.0.1 -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nextcloud.baza.state_params["имя_ключа"] -nubes_nextcloud.baza.state_out["имя_ключа"] -nubes_nextcloud.baza.state_params_flat["имя_ключа"] -nubes_nextcloud.baza.state_out_flat["имя_ключа"] -nubes_nextcloud.baza.vault_secrets["имя_ключа"] -nubes_nextcloud.baza.vault_url -nubes_nextcloud.baza.vault_user_path -nubes_nextcloud.baza.vault_fields -``` diff --git a/generated/prod/docs/nextcloud_ops.md b/generated/prod/docs/nextcloud_ops.md deleted file mode 100644 index 2dd5b5f..0000000 --- a/generated/prod/docs/nextcloud_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nextcloud_params_create.md) -- `delete` — DEV-Ветка удаления Nextcloud -- `modify` — Изменение кластера. Параметры: [Modify params](nextcloud_params_modify.md) -- `restart` -- `resume` -- `suspend` diff --git a/generated/prod/docs/nextcloud_outputs.md b/generated/prod/docs/nextcloud_outputs.md deleted file mode 100644 index 1a8707b..0000000 --- a/generated/prod/docs/nextcloud_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/nextcloud_params.md b/generated/prod/docs/nextcloud_params.md deleted file mode 100644 index 2c1eb71..0000000 --- a/generated/prod/docs/nextcloud_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Parameters - -- [Create params](nextcloud_params_create.md) -- [Modify params](nextcloud_params_modify.md) diff --git a/generated/prod/docs/nextcloud_params_create.md b/generated/prod/docs/nextcloud_params_create.md deleted file mode 100644 index b3e6a19..0000000 --- a/generated/prod/docs/nextcloud_params_create.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
564psql_uiduuidref_svc_id=90
570redis_uiduuidref_svc_id=91
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
21domainstringweb01Наименование домена. Если будет указан FQDN, то происходят проверки DNS. Если указан поддомен, то будет добавлен в зону services.ngcloud.ru
Можно указать клиентскую DNS-Запись. Важно, чтобы запись смотрела на Ingress кластера
regex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
99resource_cpuinteger1000Квота ядра пода (Указывается в mili). 1 ядро = 1000 Miliminvalue=100; maxvalue=4000
100resource_memoryinteger1024Квота памяти пода (Указывается в Megabytes)minvalue=1024; maxvalue=8192
101resource_diskinteger2Квота диска (Указывается в GIGAbytes)minvalue=2; maxvalue=999
192document_serverstringcollaboraВыбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступенvalue_list=collabora
470resource_instancesinteger1Количество узлов
Не может пока быть больше одного, так как нужны SC под RWMany
minvalue=1; maxvalue=7; value_list=1
569app_version32.0.1value_list=32.0.1
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/nextcloud_params_modify.md b/generated/prod/docs/nextcloud_params_modify.md deleted file mode 100644 index 4da066d..0000000 --- a/generated/prod/docs/nextcloud_params_modify.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Modify params - - - - - - - - - -
IDCodeTypeDescriptionConstraints
178resource_cpuintegerКвота ядра пода (Указывается в mili)minvalue=100; maxvalue=4000
179resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
180resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
547resource_instancesintegerКоличество узлов.
Не может пока быть больше одного, так как нужны SC под RWMany
minvalue=1; maxvalue=7; value_list=1
571app_versionstringНельзя обновляться сразу через несколько версий сразуvalue_list=32.0.1
diff --git a/generated/prod/docs/nifi.md b/generated/prod/docs/nifi.md deleted file mode 100644 index cf2c590..0000000 --- a/generated/prod/docs/nifi.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/nifi_example.md b/generated/prod/docs/nifi_example.md deleted file mode 100644 index 5e78168..0000000 --- a/generated/prod/docs/nifi_example.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Copy-ready manifest (`nifi_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_nifi" "baza" { - kafka_uid = "TODO" # Выбрать кластер из списка - partitions = 1 # Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - replicas = 1 # Количество партиций ≤ (число брокеров). Пример `2` - name_topic = "TODO" # Пример: `orders-events` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nifi.baza.state_params["имя_ключа"] -nubes_nifi.baza.state_out["имя_ключа"] -nubes_nifi.baza.state_params_flat["имя_ключа"] -nubes_nifi.baza.state_out_flat["имя_ключа"] -nubes_nifi.baza.vault_secrets["имя_ключа"] -nubes_nifi.baza.vault_url -nubes_nifi.baza.vault_user_path -nubes_nifi.baza.vault_fields -``` diff --git a/generated/prod/docs/nifi_ops.md b/generated/prod/docs/nifi_ops.md deleted file mode 100644 index a896c6a..0000000 --- a/generated/prod/docs/nifi_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nifi_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](nifi_params_modify.md) diff --git a/generated/prod/docs/nifi_outputs.md b/generated/prod/docs/nifi_outputs.md deleted file mode 100644 index 976b25e..0000000 --- a/generated/prod/docs/nifi_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/nifi_params.md b/generated/prod/docs/nifi_params.md deleted file mode 100644 index 4dcadac..0000000 --- a/generated/prod/docs/nifi_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Parameters - -- [Create params](nifi_params_create.md) -- [Modify params](nifi_params_modify.md) diff --git a/generated/prod/docs/nifi_params_create.md b/generated/prod/docs/nifi_params_create.md deleted file mode 100644 index d5c4baa..0000000 --- a/generated/prod/docs/nifi_params_create.md +++ /dev/null @@ -1,23 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
471kafka_uiduuidВыбрать кластер из спискаref_svc_id=116
472partitionsintegerОбратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.
473replicasintegerКоличество партиций ≤ (число брокеров). Пример `2`
474name_topicstringПример: `orders-events`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/prod/docs/nifi_params_modify.md b/generated/prod/docs/nifi_params_modify.md deleted file mode 100644 index 7f34ef0..0000000 --- a/generated/prod/docs/nifi_params_modify.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Modify params - - - - - - -
IDCodeTypeDescriptionConstraints
477partitionsintegerОбратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.
478replicasintegerКоличество партиций ≤ (число брокеров). Пример `2`
diff --git a/generated/prod/docs/nodejs.md b/generated/prod/docs/nodejs.md deleted file mode 100644 index 020cc2f..0000000 --- a/generated/prod/docs/nodejs.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## MAN - -
-Развертывает контейнер в k8s кластере с node:16, который можно использовать для запуска своих приложений.
Приложение должно быть доступно по ссылки в git репозитории, которая является входным параметром. -
diff --git a/generated/prod/docs/nodejs_example.md b/generated/prod/docs/nodejs_example.md deleted file mode 100644 index 2e77f32..0000000 --- a/generated/prod/docs/nodejs_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Copy-ready manifest (`nodejs_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_nodejs" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - git_path = "https://github.com/xahys/testnode.git" # Путь до Git, который будет webroot для сайта - resource_cpu = 500 # Квота ядра пода (milicores). 1000Mili = 1 Ядро - resource_memory = 1024 # Квота памяти пода (MBytes) - resource_instances = 1 # Количество узлов - app_version = 23 # Версия приложения -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nodejs.baza.state_params["имя_ключа"] -nubes_nodejs.baza.state_out["имя_ключа"] -nubes_nodejs.baza.state_params_flat["имя_ключа"] -nubes_nodejs.baza.state_out_flat["имя_ключа"] -nubes_nodejs.baza.vault_secrets["имя_ключа"] -nubes_nodejs.baza.vault_url -nubes_nodejs.baza.vault_user_path -nubes_nodejs.baza.vault_fields -``` diff --git a/generated/prod/docs/nodejs_ops.md b/generated/prod/docs/nodejs_ops.md deleted file mode 100644 index de1e172..0000000 --- a/generated/prod/docs/nodejs_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nodejs_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](nodejs_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/prod/docs/nodejs_outputs.md b/generated/prod/docs/nodejs_outputs.md deleted file mode 100644 index 5fa8a14..0000000 --- a/generated/prod/docs/nodejs_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/prod/docs/nodejs_params.md b/generated/prod/docs/nodejs_params.md deleted file mode 100644 index daf96ca..0000000 --- a/generated/prod/docs/nodejs_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Parameters - -- [Create params](nodejs_params_create.md) -- [Modify params](nodejs_params_modify.md) diff --git a/generated/prod/docs/nodejs_params_create.md b/generated/prod/docs/nodejs_params_create.md deleted file mode 100644 index 1bf4766..0000000 --- a/generated/prod/docs/nodejs_params_create.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
151health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет
152json_envjsonМассив переменных, будут переданы в env приложения
156resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
149domainstringweb01Наименование поддомена, будет добавлено в nodejs.dev.nubes.ruregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
150git_pathstringhttps://github.com/xahys/testnode.gitПуть до Git, который будет webroot для сайта
153resource_cpuinteger500Квота ядра пода (milicores). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
154resource_memoryinteger1024Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
155resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
270app_versionstring23Версия приложенияregex=^(\d){2}$; value_list=18, 20, 22, 23
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/nodejs_params_modify.md b/generated/prod/docs/nodejs_params_modify.md deleted file mode 100644 index 89a753e..0000000 --- a/generated/prod/docs/nodejs_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
157git_pathstringПуть до Git, который будет webroot для сайта
158health_pathstringПуть до healtcheck для запуска пода в Kubernetes, который отдаст 200 код.
159json_envjsonМассив переменных, будут переданы в env приложенияmaxlength=2048
160resource_cpuintegerКвота ядра пода (Указывается в mili) 1000Mili = 1 ядроminvalue=100; maxvalue=4000
161resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
162resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
271app_versionstringВерсия приложенияregex=^(\d){2}$; value_list=18, 20, 22, 23
diff --git a/generated/prod/docs/nodered.md b/generated/prod/docs/nodered.md deleted file mode 100644 index 54ecff3..0000000 --- a/generated/prod/docs/nodered.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/nodered_example.md b/generated/prod/docs/nodered_example.md deleted file mode 100644 index 1ccf892..0000000 --- a/generated/prod/docs/nodered_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Copy-ready manifest (`nodered_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_nodered" "baza" { - resource_realm = "TODO" # Платформа для развертывания - domain = "TODO" # Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nodered.baza.state_params["имя_ключа"] -nubes_nodered.baza.state_out["имя_ключа"] -nubes_nodered.baza.state_params_flat["имя_ключа"] -nubes_nodered.baza.state_out_flat["имя_ключа"] -nubes_nodered.baza.vault_secrets["имя_ключа"] -nubes_nodered.baza.vault_url -nubes_nodered.baza.vault_user_path -nubes_nodered.baza.vault_fields -``` diff --git a/generated/prod/docs/nodered_ops.md b/generated/prod/docs/nodered_ops.md deleted file mode 100644 index 2d6074e..0000000 --- a/generated/prod/docs/nodered_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nodered_params_create.md) -- `delete` diff --git a/generated/prod/docs/nodered_outputs.md b/generated/prod/docs/nodered_outputs.md deleted file mode 100644 index 74e4213..0000000 --- a/generated/prod/docs/nodered_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/nodered_params.md b/generated/prod/docs/nodered_params.md deleted file mode 100644 index 60a797d..0000000 --- a/generated/prod/docs/nodered_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Parameters - -- [Create params](nodered_params_create.md) -- [Modify params](nodered_params_modify.md) diff --git a/generated/prod/docs/nodered_params_create.md b/generated/prod/docs/nodered_params_create.md deleted file mode 100644 index f976ccb..0000000 --- a/generated/prod/docs/nodered_params_create.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
196resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
197domainstringНаименование поддомена, будет добавлено в k8stemplate.dev.nubes.ruregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
193resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
194resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
195resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
323resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
diff --git a/generated/prod/docs/nodered_params_modify.md b/generated/prod/docs/nodered_params_modify.md deleted file mode 100644 index be00f3b..0000000 --- a/generated/prod/docs/nodered_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/openwhisk.md b/generated/prod/docs/openwhisk.md deleted file mode 100644 index 059ed46..0000000 --- a/generated/prod/docs/openwhisk.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## MAN - -
-Добавление и удаления пользователя для работы с Openwhisk -
diff --git a/generated/prod/docs/openwhisk_example.md b/generated/prod/docs/openwhisk_example.md deleted file mode 100644 index d98bba9..0000000 --- a/generated/prod/docs/openwhisk_example.md +++ /dev/null @@ -1,44 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Copy-ready manifest (`openwhisk_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_openwhisk" "baza" { - username = "TODO" # Имя пользователя Openwhisk - resource_realm = "TODO" # Ресурсная платформа -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_openwhisk.baza.state_params["имя_ключа"] -nubes_openwhisk.baza.state_out["имя_ключа"] -nubes_openwhisk.baza.state_params_flat["имя_ключа"] -nubes_openwhisk.baza.state_out_flat["имя_ключа"] -nubes_openwhisk.baza.vault_secrets["имя_ключа"] -nubes_openwhisk.baza.vault_url -nubes_openwhisk.baza.vault_user_path -nubes_openwhisk.baza.vault_fields -``` diff --git a/generated/prod/docs/openwhisk_ops.md b/generated/prod/docs/openwhisk_ops.md deleted file mode 100644 index 91fee4e..0000000 --- a/generated/prod/docs/openwhisk_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](openwhisk_params_create.md) -- `delete` diff --git a/generated/prod/docs/openwhisk_outputs.md b/generated/prod/docs/openwhisk_outputs.md deleted file mode 100644 index e2cdfe5..0000000 --- a/generated/prod/docs/openwhisk_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/openwhisk_params.md b/generated/prod/docs/openwhisk_params.md deleted file mode 100644 index 1a9b0e5..0000000 --- a/generated/prod/docs/openwhisk_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Parameters - -- [Create params](openwhisk_params_create.md) -- [Modify params](openwhisk_params_modify.md) diff --git a/generated/prod/docs/openwhisk_params_create.md b/generated/prod/docs/openwhisk_params_create.md deleted file mode 100644 index e933788..0000000 --- a/generated/prod/docs/openwhisk_params_create.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
64usernamestringИмя пользователя Openwhisk
863resource_realmstringРесурсная платформаfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/prod/docs/openwhisk_params_modify.md b/generated/prod/docs/openwhisk_params_modify.md deleted file mode 100644 index 7791043..0000000 --- a/generated/prod/docs/openwhisk_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/pgadmin.md b/generated/prod/docs/pgadmin.md deleted file mode 100644 index 5c2feaf..0000000 --- a/generated/prod/docs/pgadmin.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## MAN - -
-Инструмент с графическим интерфейсом для управления базами данных PostgreSQL -
diff --git a/generated/prod/docs/pgadmin_example.md b/generated/prod/docs/pgadmin_example.md deleted file mode 100644 index 978be3b..0000000 --- a/generated/prod/docs/pgadmin_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Copy-ready manifest (`pgadmin_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_pgadmin" "baza" { - resource_realm = "TODO" # Платформа для развертывания - login = "TODO" # Логин для подключения к pgAdmin, в формате email (login@email.net) - password = "TODO" # Пароль для подключения к pgAdmin - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 200 # Квота ядра пода (milicores). 1000Mili = 1 Ядро - resource_memory = 256 # Квота памяти пода (MBytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_pgadmin.baza.state_params["имя_ключа"] -nubes_pgadmin.baza.state_out["имя_ключа"] -nubes_pgadmin.baza.state_params_flat["имя_ключа"] -nubes_pgadmin.baza.state_out_flat["имя_ключа"] -nubes_pgadmin.baza.vault_secrets["имя_ключа"] -nubes_pgadmin.baza.vault_url -nubes_pgadmin.baza.vault_user_path -nubes_pgadmin.baza.vault_fields -``` diff --git a/generated/prod/docs/pgadmin_ops.md b/generated/prod/docs/pgadmin_ops.md deleted file mode 100644 index 7449f5e..0000000 --- a/generated/prod/docs/pgadmin_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](pgadmin_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](pgadmin_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/prod/docs/pgadmin_outputs.md b/generated/prod/docs/pgadmin_outputs.md deleted file mode 100644 index a88297a..0000000 --- a/generated/prod/docs/pgadmin_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/prod/docs/pgadmin_params.md b/generated/prod/docs/pgadmin_params.md deleted file mode 100644 index 3afd95c..0000000 --- a/generated/prod/docs/pgadmin_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Parameters - -- [Create params](pgadmin_params_create.md) -- [Modify params](pgadmin_params_modify.md) diff --git a/generated/prod/docs/pgadmin_params_create.md b/generated/prod/docs/pgadmin_params_create.md deleted file mode 100644 index d527c72..0000000 --- a/generated/prod/docs/pgadmin_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
169resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
170loginstringЛогин для подключения к pgAdmin, в формате email (login@email.net)regex=^([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)$; maxlength=255; minlength=3
171passwordstringПароль для подключения к pgAdmin
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
164domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
165resource_cpuinteger200Квота ядра пода (milicores). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
166resource_memoryinteger256Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
167resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/pgadmin_params_modify.md b/generated/prod/docs/pgadmin_params_modify.md deleted file mode 100644 index 0b7613e..0000000 --- a/generated/prod/docs/pgadmin_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
172resource_cpuintegerКвота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
173resource_memoryintegerКвота памяти пода (MBytes)minvalue=128; maxvalue=8192
174resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
diff --git a/generated/prod/docs/postgres.md b/generated/prod/docs/postgres.md deleted file mode 100644 index 61e7668..0000000 --- a/generated/prod/docs/postgres.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## MAN - -
-# Инструкция по развертыванию PostgreSQL через платформу

---
## 1. Общая информация

PostgreSQL — это надёжная объектно-реляционная СУБД с открытым исходным кодом, поддерживающая расширенный набор функций, транзакции и хранение сложных типов данных. Развёртывание полностью автоматизировано платформой на базе Zalando Postgres Operator с использованием Kubernetes.

## Доступные операции

- **create** — Создание кластера
- **delete** — Удаление кластера
- **modify** — Модификация кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера
- **restart** — Перезапуск кластера
- **recovery** — Восстановление из резервной копии

- **create_user** — Создание пользователя
- **delete_user** — Удаление пользователя

- **create_database** — Создание базы данных
- **delete_database** — Удаление базы данных


---
## 2. Параметры развертывания кластера

Ниже перечислены параметры, которые необходимо указать при создании ресурса PostgreSQL:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество инстансов (реплик) в кластере PostgreSQL. Пример: `2` (master + slave).

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных в гигабайтах. Пример: `20`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`

* **Выделяет внешний IP для доступа к slave:**
Флаг для выделения внешнего IP для slave (реплики чтения). Работает, если slave присутствует в кластере.

* **Имя ipSpace для публикации внешнего IP slave:**
Если включен параметр для slave, то поле необходимо заполнить.

* **UUID экземпляра услуги S3:**
UUID экземпляра S3 для хранения резервных копий.

* **Версия PostgreSQL:**
Версия PostgreSQL для развертывания. Пример: `16`

* **Расписание бэкапов (ext_BACKUP_SCHEDULE):**
Необязательный. Cron-выражение для времени запуска бэкапов. По умолчанию: `0 0 * * *` (ежедневно в полночь).

* **Количество сохраняемых бэкапов (ext_BACKUP_NUM_TO_RETAIN):**
Необязательный. Количество сохраняемых бэкапов. По умолчанию: `7`

* **PgPooler (master / slave):**
Флаги включения PgBouncer для подключений на запись и чтение. При включении создаётся отдельный под.

* **Разрешить подключение без SSL (allowNoSSL):**
По умолчанию подключение с sslmode=require. При `true` разрешается подключение без SSL.

* **Автоскейлинг PV (autoScale):**
Включает автоскейлинг тома. Требует настройки autoScalePercentage, autoScaleTechWindow, autoScaleQuotaGb.

* **Дополнительные параметры PostgreSQL (jsonParameters):**
JSON с переменными конфигурации PostgreSQL. Документация: https://www.postgresql.org/docs/current/runtime-config.html

---
## 3. Выходные параметры

После успешного развертывания ресурса PostgreSQL платформа возвращает ряд параметров.

#### externalConnect

Внешние эндпоинты для подключения к кластеру:
- **master** — для операций записи (host: `write.${namespace}`, port: 5432)
- **slave** — для операций чтения (host: `read.${namespace}`, port: 5432)

Пример ответа платформы:

```json
{
"slave": {
"ip": "",
"fqdn": "",
"uuid": "",
"isExternal": false
},
"master": {
"ip": "<ip>",
"fqdn": "write.<namespace>.<cluster-domain>",
"uuid": "<uuid>",
"isExternal": false
}
}
```

Поля: `ip` — внешний IP; `fqdn` — полное имя хоста; `uuid` — идентификатор; `isExternal` — признак внешнего доступа.

#### internalConnect

Внутренние эндпоинты (FQDN) для подключения из других сервисов внутри той же сети Kubernetes.

Пример ответа платформы:

```json
{
"slave": "",
"master": {
"slave": "",
"master": {
"slave": "",
"master": "postgresqlk8s-master.<namespace>.svc.cluster.local"
}
}
}
```

Для подключения используйте значение `master.master.master` (host для записи) или соответствующее значение slave (host для чтения).

Для подключения используется порт **5432**.

---
## 4. Управление пользователями

### create_user — Создание пользователя

* **Имя пользователя (username):**
Имя создаваемого пользователя. Используется для подключения к базе и настройки прав.
Пример: `myapp_user`

* **Роль (role):**
Тип роли пользователя. Допустимые значения:
- `app_user` — базовые права для DML-операций (SELECT, INSERT, UPDATE, DELETE)
- `ddl_user` — расширенные права: createdb, createrole (управление базами и ролями)

Защищённые имена, которые нельзя использовать: `admin`, `postgres`, `standby`.

### delete_user — Удаление пользователя

* **Имя пользователя (username):**
Имя удаляемого пользователя. Пример: `myapp_user`

Пользователя нельзя удалить, если он является владельцем базы данных. Сначала удалите или передайте владение базами данных другому пользователю.

---
## 5. Управление базами данных

### create_database — Создание базы данных

* **Имя базы данных (dbName):**
Название создаваемой базы данных. Пример: `myapp_db`

* **Владелец базы данных (dbOwner):**
Имя пользователя-владельца базы. Должен существовать в кластере (создан через create_user). Пример: `myapp_user`

### delete_database — Удаление базы данных

* **Имя базы данных (dbName):**
Название удаляемой базы данных. Пример: `myapp_db`
-
diff --git a/generated/prod/docs/postgres_example.md b/generated/prod/docs/postgres_example.md deleted file mode 100644 index fea5133..0000000 --- a/generated/prod/docs/postgres_example.md +++ /dev/null @@ -1,63 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Copy-ready manifest (`postgres_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_postgres" "baza" { - s3_uid = "TODO" # Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_instances = 1 # Количество узлов - resource_memory = 512 # Квота памяти пода (MBytes) - resource_cpu = 500 # Квота ядра пода (milicores) - resource_disk = 10 # Квота диска (Указывается в GIGAbytes) - need_external_address_master = false # Выделяет внешний (белый) IP для доступа к master - need_external_address_slave = false # Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть - ext_backup_schedule = "0 0 * * *" # Не обязательный. Время запуска бекапа - ext_backup_num_to_retain = 7 # Не обязательный. Количество сохраняемых бекапов - app_version = 17 # Версия PostgreSQL - json_parameters = { "log_connections": "off", "log_disconnections": "off" } # Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html - enable_pg_pooler_master = false # Включает pgPooler (на запись). Будет создан новый под - enable_pg_pooler_slave = false # Включает pgPooler (на чтение). Будет создан новый под - allow_no_ssl = false # По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр - auto_scale = false # Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги - auto_scale_percentage = 10 # Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема - auto_scale_tech_window = 0 # Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) - auto_scale_quota_gb = 1 # Квота для autoScale -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_postgres.baza.state_params["имя_ключа"] -nubes_postgres.baza.state_out["имя_ключа"] -nubes_postgres.baza.state_params_flat["имя_ключа"] -nubes_postgres.baza.state_out_flat["имя_ключа"] -nubes_postgres.baza.vault_secrets["имя_ключа"] -nubes_postgres.baza.vault_url -nubes_postgres.baza.vault_user_path -nubes_postgres.baza.vault_fields -``` diff --git a/generated/prod/docs/postgres_ops.md b/generated/prod/docs/postgres_ops.md deleted file mode 100644 index ebe3b5c..0000000 --- a/generated/prod/docs/postgres_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](postgres_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](postgres_params_modify.md) -- `recovery` -- `restart` — ВНИМАНИЕ - Рестарт предполагает УДАЛЕНИЕ подов. Может быть полная поломка. Крайне осторожно запускать при работе -- `resume` -- `suspend` diff --git a/generated/prod/docs/postgres_outputs.md b/generated/prod/docs/postgres_outputs.md deleted file mode 100644 index f07b697..0000000 --- a/generated/prod/docs/postgres_outputs.md +++ /dev/null @@ -1,65 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.master"]` -- `state_out_flat["externalConnect.master.fqdn"]` -- `state_out_flat["externalConnect.master.ip"]` -- `state_out_flat["externalConnect.master.isExternal"]` -- `state_out_flat["externalConnect.master.uuid"]` -- `state_out_flat["externalConnect.slave"]` -- `state_out_flat["externalConnect.slave.fqdn"]` -- `state_out_flat["externalConnect.slave.ip"]` -- `state_out_flat["externalConnect.slave.isExternal"]` -- `state_out_flat["externalConnect.slave.uuid"]` -- `state_out_flat["internalConnect"]` -- `state_out_flat["internalConnect.master"]` -- `state_out_flat["internalConnect.slave"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.k8spostgresql"]` -- `state_out_flat["monitoring.k8spostgresql.url"]` -- `state_out_flat["monitoring.k8spostgresqlbackup"]` -- `state_out_flat["monitoring.k8spostgresqlbackup.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` -- `vault_secrets["standbyPass"]` -- `vault_secrets["standbyUser"]` - -### Пример для связки с Lucee/NodeJS - -```hcl -testds_connectionString = "jdbc:postgresql://${nubes_postgres.db2.state_out_flat["internalConnect.master"]}:5432/postgres?sslmode=require" -testds_username = nubes_postgres.db2.vault_secrets["adminUser"] -testds_password = nubes_postgres.db2.vault_secrets["adminPass"] -``` diff --git a/generated/prod/docs/postgres_params.md b/generated/prod/docs/postgres_params.md deleted file mode 100644 index b44e9f4..0000000 --- a/generated/prod/docs/postgres_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Parameters - -- [Create params](postgres_params_create.md) -- [Modify params](postgres_params_modify.md) diff --git a/generated/prod/docs/postgres_params_create.md b/generated/prod/docs/postgres_params_create.md deleted file mode 100644 index 69a72bb..0000000 --- a/generated/prod/docs/postgres_params_create.md +++ /dev/null @@ -1,55 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
23s3_uiduuidЭкземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательноref_svc_id=12
102resource_realmstringКластер Kubernetes, на котором будет развернут экземплярfunc=getAvailableResourceRealms
337ip_space_name_masterstringИмя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`
338ip_space_name_slavestringИмя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
80resource_instancesinteger1Количество узлов в кластере. 1,3,5,7minvalue=1; maxvalue=7; regex=^[1357]$
81resource_memoryinteger512Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
82resource_cpuinteger500Квота ядра пода (milicores)minvalue=100; maxvalue=4000
83resource_disk10Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
145need_external_address_masterbooleanfalseВыделяет внешний (белый) IP для доступа к mastervalue_list=false, true
146need_external_address_slavebooleanfalseВыделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе естьvalue_list=false, true
265ext_backup_schedulestring0 0 * * *Не обязательный. Время запуска бекапаregex=^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$
266ext_backup_num_to_retaininteger7Не обязательный. Количество сохраняемых бекаповminvalue=1; maxvalue=99
310app_versionstring17Версия PostgreSQLvalue_list=17, 16, 15, 14, 13
311json_parametersjson{ "log_connections": "off", "log_disconnections": "off" }Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.htmlmaxlength=2048
312enable_pg_pooler_masterbooleanfalseВключает pgPooler (на запись). Будет создан новый подvalue_list=false, true
313enable_pg_pooler_slavebooleanfalseВключает pgPooler (на чтение). Будет создан новый подvalue_list=false, true
314allow_no_sslbooleanfalseПо умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметрvalue_list=false, true
329auto_scalebooleanfalseВключает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услугиvalue_list=false, true
330auto_scale_percentageinteger10Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объемаvalue_list=10, 15, 20
331auto_scale_tech_windowinteger0Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23)value_list=0, 5, 12, 23
339auto_scale_quota_gbstring1Квота для autoScale
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/postgres_params_modify.md b/generated/prod/docs/postgres_params_modify.md deleted file mode 100644 index 2fcc3af..0000000 --- a/generated/prod/docs/postgres_params_modify.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Modify params - - - - - - - - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
91resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
92resource_memoryintegerКвота памяти пода (MBytes)minvalue=128; maxvalue=8192
93resource_cpuintegerКвота ядра пода (milicores)minvalue=100; maxvalue=4000
94resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
147need_external_address_masterbooleanВыделяет внешний IP для доступа к mastervalue_list=false, true
148need_external_address_slavebooleanВыделяет внешний IP для доступа к slave. Действует, если slave в принципе естьvalue_list=false, true
267ext_backup_schedulestringНе обязательный. Время запуска бекапаregex=^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$
268ext_backup_num_to_retainintegerНе обязательный. Количество сохраняемых бекаповminvalue=1; maxvalue=99
315app_versionstringВерсия PostgreSQL. Нельзя опускать внизvalue_list=17, 16, 15, 14, 13
316json_parametersjsonМассив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.htmlmaxlength=2048
317enable_pg_pooler_masterbooleanВключает pgPooler (на запись). Будет создан новый подvalue_list=false, true
318enable_pg_pooler_slavebooleanВключает pgPooler (на чтение). Будет создан новый подvalue_list=false, true
319allow_no_sslbooleanПо умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметрvalue_list=false, true
541ip_space_name_masterstringИмя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`
542ip_space_name_slavestringИмя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave
diff --git a/generated/prod/docs/rabbitmq.md b/generated/prod/docs/rabbitmq.md deleted file mode 100644 index d0e5af3..0000000 --- a/generated/prod/docs/rabbitmq.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## MAN - -
-# Инструкция по развертыванию RabbitMQ через платформу

---
## 1. Общая информация
RabbitMQ — это брокер сообщений с открытым исходным кодом, который обеспечивает надёжную доставку сообщений между приложениями.
Позволяет надёжно передавать сообщения между сервисами и системами, интегрироваться с внешними решениями и использовать как внутренние, так и защищённые TLS-подключения. Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание кластера
- **modify** — Изменение параметров кластера
- **delete** — Удаление кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера


---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса RabbitMQ:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество реплик в кластере RabbitMQ. При значении больше 1 создаётся кластер с репликацией для обеспечения высокой доступности.
Пример: `1` (single node) или `3` (кластер с репликацией)

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных RabbitMQ в гигабайтах. Пример: `50`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-узлу. При включении создаётся Service типа LoadBalancer и настраивается VIP на порту 5672.
Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`


---
## 3. Модификация кластера
Операция **modify** позволяет изменить параметры существующего кластера RabbitMQ.

**Изменяемые параметры:**
* **Квота (megabyte) памяти пода** — можно увеличить или уменьшить
* **Квота (millicore) ядра пода** — можно увеличить или уменьшить
* **Размер (gigabyte) диска для базы данных** — можно только увеличить (уменьшение не поддерживается)
* **Количество узлов в сети** — можно только увеличить (уменьшение не поддерживается)
* **Выделяет внешний IP для доступа к master** — можно включить или выключить
* **Имя ipSpace для публикации внешнего IP master** — можно изменить при включенном внешнем IP

**Ограничения:**
* Уменьшение размера диска не поддерживается
* Уменьшение количества реплик не поддерживается

---
## 4. Выходные параметры
После успешного развертывания ресурса RabbitMQ платформа возвращает ряд параметров в разделе "Поля состояния (сгенерированные значения)":

**clusterDomain**
Домен кластера Kubernetes, в котором развернут RabbitMQ.
Пример: `cluster.local`

**inernalConnect**
Внутренние эндпоинты для подключения к кластеру RabbitMQ из других сервисов, развернутых внутри той же сети.
Содержит:
* **master** — FQDN для подключения к кластеру. Пример: `rabbitmqk8s.{namespace}.svc.{clusterDomain}`

**externalConnect**
Внешние эндпоинты для подключения к кластеру RabbitMQ извне.
Содержит объекты с полями:
* **admin** — доступ к веб-интерфейсу управления:
* `fqdn` — полное доменное имя для веб-интерфейса. Пример: `admin.{namespace}.{domain}`
* `ip` — IP-адрес
* **master** — доступ к AMQP протоколу (если включен внешний IP):
* `fqdn` — полное доменное имя для AMQP. Пример: `write.{namespace}.{domain}`
* `ip` — IP-адрес

**monitoring**
Информация о дашбордах мониторинга:
* **allDashboards** — URL для доступа ко всем дашбордам Grafana

Для подключения используются следующие порты:

* **5672** — AMQP протокол (внутренний и внешний доступ, если включен внешний IP)
* **15672** — веб-интерфейс управления (доступен через Ingress по HTTPS)

**Учётные данные**
Данные для подключения к RabbitMQ доступны в разделе "Учётные данные":
* **adminUser** — имя пользователя администратора
* **adminPass** — пароль администратора


---
## 5. Примеры подключения через консоль (rabbitmqadmin)

### Работа с очередями через rabbitmqadmin

Для работы с RabbitMQ через консоль используется утилита `rabbitmqadmin`. Установите её или используйте образ с предустановленной утилитой.

Задайте переменные окружения с учётными данными:

```bash
export RABBITMQ_USERNAME=<adminUser>
export RABBITMQ_PASSWORD=<adminPass>
export RABBIT_HOST=<host>
```

Где:
* `<adminUser>` и `<adminPass>` — учётные данные из раздела "Учётные данные"
* `<host>` — адрес для подключения:
* Для внешнего подключения: `externalConnect.admin.fqdn` или `externalConnect.master.fqdn`

**Создание очереди:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
declare queue name=healthcheck durable=false
```

**Листинг очередей:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
list queues
```

**Отправка сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
publish exchange=amq.default routing_key=healthcheck payload="ping-$(date +%s)"
```

**Чтение сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
get queue=healthcheck ackmode=ack_requeue_false
```

---
## 6. Дополнительная информация
Для подключения к кластеру RabbitMQ используйте полученные эндпоинты из раздела "Поля состояния (сгенерированные значения)" и учётные данные из раздела "Учётные данные".

Веб-интерфейс управления доступен по адресу, указанному в параметре `externalConnect.admin.fqdn` через HTTPS.

Для внутреннего подключения используйте адрес из `inernalConnect.master` на порту 5672.

--- -
diff --git a/generated/prod/docs/rabbitmq_example.md b/generated/prod/docs/rabbitmq_example.md deleted file mode 100644 index f1a4f26..0000000 --- a/generated/prod/docs/rabbitmq_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Copy-ready manifest (`rabbitmq_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_rabbitmq" "baza" { - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 1000 # Пример: `2000` - resource_memory = 1124 # Пример: `2048` - resource_disk = 30 # Пример: `20` - resource_instances = 1 # Пример: `1` - need_external_address_master = false # Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_rabbitmq.baza.state_params["имя_ключа"] -nubes_rabbitmq.baza.state_out["имя_ключа"] -nubes_rabbitmq.baza.state_params_flat["имя_ключа"] -nubes_rabbitmq.baza.state_out_flat["имя_ключа"] -nubes_rabbitmq.baza.vault_secrets["имя_ключа"] -nubes_rabbitmq.baza.vault_url -nubes_rabbitmq.baza.vault_user_path -nubes_rabbitmq.baza.vault_fields -``` diff --git a/generated/prod/docs/rabbitmq_ops.md b/generated/prod/docs/rabbitmq_ops.md deleted file mode 100644 index fe63cf6..0000000 --- a/generated/prod/docs/rabbitmq_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](rabbitmq_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](rabbitmq_params_modify.md) -- `resume` -- `suspend` — Пока не работает из за того что RabbitmqCluster нельзя занулить diff --git a/generated/prod/docs/rabbitmq_outputs.md b/generated/prod/docs/rabbitmq_outputs.md deleted file mode 100644 index 30d870e..0000000 --- a/generated/prod/docs/rabbitmq_outputs.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["clusterDomain"]` -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.admin"]` -- `state_out_flat["externalConnect.admin.fqdn"]` -- `state_out_flat["externalConnect.admin.ip"]` -- `state_out_flat["externalConnect.admin.isExternal"]` -- `state_out_flat["externalConnect.admin.uuid"]` -- `state_out_flat["inernalConnect"]` -- `state_out_flat["inernalConnect.master"]` -- `state_out_flat["inernalConnect.slave"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` - diff --git a/generated/prod/docs/rabbitmq_params.md b/generated/prod/docs/rabbitmq_params.md deleted file mode 100644 index b743d18..0000000 --- a/generated/prod/docs/rabbitmq_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Parameters - -- [Create params](rabbitmq_params_create.md) -- [Modify params](rabbitmq_params_modify.md) diff --git a/generated/prod/docs/rabbitmq_params_create.md b/generated/prod/docs/rabbitmq_params_create.md deleted file mode 100644 index 1a1b21f..0000000 --- a/generated/prod/docs/rabbitmq_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
119resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
543ip_space_name_masterstringПример: `internet-no-antiddos-v1`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
116resource_cpuinteger1000Пример: `2000`minvalue=500; maxvalue=4000
117resource_memoryinteger1124Пример: `2048`minvalue=512; maxvalue=8192
118resource_diskinteger30Пример: `20`minvalue=5; maxvalue=999
224resource_instancesinteger1Пример: `1`minvalue=1; maxvalue=7
225need_external_address_masterbooleanfalseФлаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`value_list=false, true
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/rabbitmq_params_modify.md b/generated/prod/docs/rabbitmq_params_modify.md deleted file mode 100644 index bdd6224..0000000 --- a/generated/prod/docs/rabbitmq_params_modify.md +++ /dev/null @@ -1,22 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Modify params - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
304resource_cpuintegerПример: `2000`minvalue=500; maxvalue=4000
305resource_memoryintegerПример: `2048`minvalue=512; maxvalue=8192
306resource_diskintegerПример: `20`minvalue=1; maxvalue=999
307resource_instancesintegerПример: `1`minvalue=1; maxvalue=7
308need_external_address_masterbooleanВыделяет внешний (белый) IP для доступа к mastervalue_list=false, true
309need_external_address_slavebooleanВыделяет внешний (белый) IP для доступа к slavevalue_list=false, true
545ip_space_name_masterstringПример: `internet-no-antiddos-v1`
546ip_space_name_slavestringПример: `internet-no-antiddos-v1`
diff --git a/generated/prod/docs/redis.md b/generated/prod/docs/redis.md deleted file mode 100644 index 4dfd2ea..0000000 --- a/generated/prod/docs/redis.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## MAN - -
-Redis кластер. Под кеши.
Ресурсная платформа: k8s.
Автоматизация: k8s operator
port 6379 -
diff --git a/generated/prod/docs/redis_example.md b/generated/prod/docs/redis_example.md deleted file mode 100644 index c1dd1d9..0000000 --- a/generated/prod/docs/redis_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Copy-ready manifest (`redis_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_redis" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 1000 # Квота ядра пода (Указывается в mili) - resource_memory = 1024 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 30 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - need_external_address_master = false # Выделяет внешний IP для доступа к master - need_external_address_slave = false # Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_redis.baza.state_params["имя_ключа"] -nubes_redis.baza.state_out["имя_ключа"] -nubes_redis.baza.state_params_flat["имя_ключа"] -nubes_redis.baza.state_out_flat["имя_ключа"] -nubes_redis.baza.vault_secrets["имя_ключа"] -nubes_redis.baza.vault_url -nubes_redis.baza.vault_user_path -nubes_redis.baza.vault_fields -``` diff --git a/generated/prod/docs/redis_ops.md b/generated/prod/docs/redis_ops.md deleted file mode 100644 index d5d813c..0000000 --- a/generated/prod/docs/redis_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](redis_params_create.md) -- `delete` diff --git a/generated/prod/docs/redis_outputs.md b/generated/prod/docs/redis_outputs.md deleted file mode 100644 index c735f67..0000000 --- a/generated/prod/docs/redis_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/redis_params.md b/generated/prod/docs/redis_params.md deleted file mode 100644 index 131dd5e..0000000 --- a/generated/prod/docs/redis_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Parameters - -- [Create params](redis_params_create.md) -- [Modify params](redis_params_modify.md) diff --git a/generated/prod/docs/redis_params_create.md b/generated/prod/docs/redis_params_create.md deleted file mode 100644 index 2dccb7e..0000000 --- a/generated/prod/docs/redis_params_create.md +++ /dev/null @@ -1,31 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
182resource_realmstringНаименование кластера Kubernetes для подключения
func=getAvailableResourceRealms
548ip_space_name_masterstringИмя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster
549ip_space_name_slavestringИмя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
112resource_cpuinteger1000Квота ядра пода (Указывается в mili)minvalue=500; maxvalue=4000
113resource_memoryinteger1024Квота памяти пода (Указывается в Megabytes)minvalue=512; maxvalue=8192
114resource_diskinteger30Квота диска (Указывается в GIGAbytes)minvalue=10; maxvalue=999
181resource_instancesinteger1Количество узлов в сети. Если выделить больше 1 ноды, будет добавлено дополнительно 3 Sentinel нодыminvalue=1; maxvalue=7
183need_external_address_masterbooleanfalseВыделяет внешний IP для доступа к mastervalue_list=false, true
184need_external_address_slavebooleanfalseВыделяет внешний IP для доступа к slave. Будет работать если slave в целом естьvalue_list=false, true
diff --git a/generated/prod/docs/redis_params_modify.md b/generated/prod/docs/redis_params_modify.md deleted file mode 100644 index 7461280..0000000 --- a/generated/prod/docs/redis_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/s3.md b/generated/prod/docs/s3.md deleted file mode 100644 index 15a87a0..0000000 --- a/generated/prod/docs/s3.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## MAN - -
-Руководство доступно по ссылке:
https://docs.s3.msk-1.ngcloud.ru/s3/s3.description.html -
diff --git a/generated/prod/docs/s3_example.md b/generated/prod/docs/s3_example.md deleted file mode 100644 index 0c02b26..0000000 --- a/generated/prod/docs/s3_example.md +++ /dev/null @@ -1,44 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Copy-ready manifest (`s3_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_s3" "baza" { - resource_realm = "TODO" # Платформа для развертывания - display_name = "TODO" # Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_s3.baza.state_params["имя_ключа"] -nubes_s3.baza.state_out["имя_ключа"] -nubes_s3.baza.state_params_flat["имя_ключа"] -nubes_s3.baza.state_out_flat["имя_ключа"] -nubes_s3.baza.vault_secrets["имя_ключа"] -nubes_s3.baza.vault_url -nubes_s3.baza.vault_user_path -nubes_s3.baza.vault_fields -``` diff --git a/generated/prod/docs/s3_ops.md b/generated/prod/docs/s3_ops.md deleted file mode 100644 index d030e69..0000000 --- a/generated/prod/docs/s3_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](s3_params_create.md) -- `create_sub_user` — Создание кластера. Параметры: [Create params](s3_params_create.md) -- `delete` -- `delete_sub_user` -- `modify` — Изменение кластера. Параметры: [Modify params](s3_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/s3_outputs.md b/generated/prod/docs/s3_outputs.md deleted file mode 100644 index e1cdeb2..0000000 --- a/generated/prod/docs/s3_outputs.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dtEndTrial"]` -- `state_out_flat["dtStartTrial"]` -- `state_out_flat["isTrial"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.s3ceph"]` -- `state_out_flat["monitoring.s3ceph.url"]` -- `state_out_flat["urlConnect"]` - -### `vault_secrets` ключи - -- `vault_secrets["1325_access_key"]` -- `vault_secrets["1325_secret_key"]` -- `vault_secrets["1325_technicalS3Backup_access_key"]` -- `vault_secrets["1325_technicalS3Backup_secret_key"]` - diff --git a/generated/prod/docs/s3_params.md b/generated/prod/docs/s3_params.md deleted file mode 100644 index d61aced..0000000 --- a/generated/prod/docs/s3_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Parameters - -- [Create params](s3_params_create.md) -- [Modify params](s3_params_modify.md) diff --git a/generated/prod/docs/s3_params_create.md b/generated/prod/docs/s3_params_create.md deleted file mode 100644 index 743e44f..0000000 --- a/generated/prod/docs/s3_params_create.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
163resource_realmкластер S3 для подключенияfunc=getAvailableResourceRealms
320display_namestringЧеловеко-читаемое имя (транслит из Elma) - передаётся имя клиента
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/s3_params_modify.md b/generated/prod/docs/s3_params_modify.md deleted file mode 100644 index d9859fc..0000000 --- a/generated/prod/docs/s3_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
50max_size_gb_per_userintegermaxSizeGb. Передаём рукамиminvalue=-1; maxvalue=50000
51max_objects_per_bucketintegerКвота на бакет. Кол-во объектов. Передаём рукамиminvalue=1; maxvalue=10000000
52max_buckets_per_userintegerКвота на пользователя. Количество бакетов пользователя. Передаём рукамиminvalue=1; maxvalue=1000
diff --git a/generated/prod/docs/s3bucket.md b/generated/prod/docs/s3bucket.md deleted file mode 100644 index 27d17d7..0000000 --- a/generated/prod/docs/s3bucket.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/s3bucket_example.md b/generated/prod/docs/s3bucket_example.md deleted file mode 100644 index 233571e..0000000 --- a/generated/prod/docs/s3bucket_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Copy-ready manifest (`s3bucket_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_s3bucket" "baza" { - s3_user_uid = "TODO" # UID Корневой услуги S3. На основе него будет создан бакет. - bucket_name = "TODO" # Имя бакета s3 - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - max_size = -1 # Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes - read_all = false # Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. - list_all = false # Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. - cors_all = false # Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS - placement = "HOT" # Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_s3bucket.baza.state_params["имя_ключа"] -nubes_s3bucket.baza.state_out["имя_ключа"] -nubes_s3bucket.baza.state_params_flat["имя_ключа"] -nubes_s3bucket.baza.state_out_flat["имя_ключа"] -nubes_s3bucket.baza.vault_secrets["имя_ключа"] -nubes_s3bucket.baza.vault_url -nubes_s3bucket.baza.vault_user_path -nubes_s3bucket.baza.vault_fields -``` diff --git a/generated/prod/docs/s3bucket_ops.md b/generated/prod/docs/s3bucket_ops.md deleted file mode 100644 index 61b2abb..0000000 --- a/generated/prod/docs/s3bucket_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](s3bucket_params_create.md) -- `delete` diff --git a/generated/prod/docs/s3bucket_outputs.md b/generated/prod/docs/s3bucket_outputs.md deleted file mode 100644 index f62a754..0000000 --- a/generated/prod/docs/s3bucket_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["httpConnect"]` - diff --git a/generated/prod/docs/s3bucket_params.md b/generated/prod/docs/s3bucket_params.md deleted file mode 100644 index 9977e26..0000000 --- a/generated/prod/docs/s3bucket_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Parameters - -- [Create params](s3bucket_params_create.md) -- [Modify params](s3bucket_params_modify.md) diff --git a/generated/prod/docs/s3bucket_params_create.md b/generated/prod/docs/s3bucket_params_create.md deleted file mode 100644 index 0ae6f44..0000000 --- a/generated/prod/docs/s3bucket_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
124s3_user_uiduuidUID Корневой услуги S3. На основе него будет создан бакет.ref_svc_id=12
125bucket_namestringИмя бакета s3
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
126max_size-1Максимальный размер бакета s3. Если поставить 0, будет безлимит. Размер указывается в Bytes
127read_allbooleanfalseПубличный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета.value_list=false, true
128list_allbooleanfalseПубличный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете.value_list=false, true
129cors_allbooleanfalseПубличный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORSvalue_list=false, true
130placementstringHOTКласс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращенияvalue_list=HOT, COLD
diff --git a/generated/prod/docs/s3bucket_params_modify.md b/generated/prod/docs/s3bucket_params_modify.md deleted file mode 100644 index ca24765..0000000 --- a/generated/prod/docs/s3bucket_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/superset.md b/generated/prod/docs/superset.md deleted file mode 100644 index 93094e9..0000000 --- a/generated/prod/docs/superset.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## MAN - -
-Apache Superset как сервис.
Ресурсная платформа: k8s.
Автоматизация: k8s operator.
Авторизация: 2FA keycloak (для доменного логина @mgmt.nubes.ru) -
diff --git a/generated/prod/docs/superset_example.md b/generated/prod/docs/superset_example.md deleted file mode 100644 index ce560e5..0000000 --- a/generated/prod/docs/superset_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Copy-ready manifest (`superset_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_superset" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - emails = "testuser1" # Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_superset.baza.state_params["имя_ключа"] -nubes_superset.baza.state_out["имя_ключа"] -nubes_superset.baza.state_params_flat["имя_ключа"] -nubes_superset.baza.state_out_flat["имя_ключа"] -nubes_superset.baza.vault_secrets["имя_ключа"] -nubes_superset.baza.vault_url -nubes_superset.baza.vault_user_path -nubes_superset.baza.vault_fields -``` diff --git a/generated/prod/docs/superset_ops.md b/generated/prod/docs/superset_ops.md deleted file mode 100644 index 5aa441d..0000000 --- a/generated/prod/docs/superset_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](superset_params_create.md) -- `delete` — DEV-Ветка удаления Superset diff --git a/generated/prod/docs/superset_outputs.md b/generated/prod/docs/superset_outputs.md deleted file mode 100644 index 4d7a1fd..0000000 --- a/generated/prod/docs/superset_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/superset_params.md b/generated/prod/docs/superset_params.md deleted file mode 100644 index 2984f1c..0000000 --- a/generated/prod/docs/superset_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Parameters - -- [Create params](superset_params_create.md) -- [Modify params](superset_params_modify.md) diff --git a/generated/prod/docs/superset_params_create.md b/generated/prod/docs/superset_params_create.md deleted file mode 100644 index 6652cf1..0000000 --- a/generated/prod/docs/superset_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
109resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
14domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
20emailsstringtestuser1Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел
96resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядроminvalue=100; maxvalue=4000
97resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
98resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
227resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
diff --git a/generated/prod/docs/superset_params_modify.md b/generated/prod/docs/superset_params_modify.md deleted file mode 100644 index 5a6e1ca..0000000 --- a/generated/prod/docs/superset_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/template.md b/generated/prod/docs/template.md deleted file mode 100644 index b4d0dc3..0000000 --- a/generated/prod/docs/template.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/template_example.md b/generated/prod/docs/template_example.md deleted file mode 100644 index e00dd7c..0000000 --- a/generated/prod/docs/template_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Copy-ready manifest (`template_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_template" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 100 - resource_memory = 200 - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_template.baza.state_params["имя_ключа"] -nubes_template.baza.state_out["имя_ключа"] -nubes_template.baza.state_params_flat["имя_ключа"] -nubes_template.baza.state_out_flat["имя_ключа"] -nubes_template.baza.vault_secrets["имя_ключа"] -nubes_template.baza.vault_url -nubes_template.baza.vault_user_path -nubes_template.baza.vault_fields -``` diff --git a/generated/prod/docs/template_ops.md b/generated/prod/docs/template_ops.md deleted file mode 100644 index 7bea1f5..0000000 --- a/generated/prod/docs/template_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](template_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](template_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/template_outputs.md b/generated/prod/docs/template_outputs.md deleted file mode 100644 index ab5623d..0000000 --- a/generated/prod/docs/template_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/template_params.md b/generated/prod/docs/template_params.md deleted file mode 100644 index 7fdd8d3..0000000 --- a/generated/prod/docs/template_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Parameters - -- [Create params](template_params_create.md) -- [Modify params](template_params_modify.md) diff --git a/generated/prod/docs/template_params_create.md b/generated/prod/docs/template_params_create.md deleted file mode 100644 index aaa56ea..0000000 --- a/generated/prod/docs/template_params_create.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
206resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
202resource_cpuinteger100minvalue=100; maxvalue=4000
203resource_memoryinteger200minvalue=128; maxvalue=8192
204resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
205resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
207domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/template_params_modify.md b/generated/prod/docs/template_params_modify.md deleted file mode 100644 index 9e15054..0000000 --- a/generated/prod/docs/template_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
208resource_cpuintegerminvalue=100; maxvalue=4000
209resource_memoryintegerminvalue=128; maxvalue=8192
210resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
211resource_instancesintegerКоличество узловminvalue=1; maxvalue=7
diff --git a/generated/prod/docs/tenant.md b/generated/prod/docs/tenant.md deleted file mode 100644 index 409820a..0000000 --- a/generated/prod/docs/tenant.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/tenant_example.md b/generated/prod/docs/tenant_example.md deleted file mode 100644 index b656a0d..0000000 --- a/generated/prod/docs/tenant_example.md +++ /dev/null @@ -1,44 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Copy-ready manifest (`tenant_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_tenant" "baza" { - grafana_org_name = "TODO" # WZ-Код клиента - resource_realm = "TODO" # Платформа для развертывания -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_tenant.baza.state_params["имя_ключа"] -nubes_tenant.baza.state_out["имя_ключа"] -nubes_tenant.baza.state_params_flat["имя_ключа"] -nubes_tenant.baza.state_out_flat["имя_ключа"] -nubes_tenant.baza.vault_secrets["имя_ключа"] -nubes_tenant.baza.vault_url -nubes_tenant.baza.vault_user_path -nubes_tenant.baza.vault_fields -``` diff --git a/generated/prod/docs/tenant_ops.md b/generated/prod/docs/tenant_ops.md deleted file mode 100644 index 5058136..0000000 --- a/generated/prod/docs/tenant_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](tenant_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](tenant_params_modify.md) diff --git a/generated/prod/docs/tenant_outputs.md b/generated/prod/docs/tenant_outputs.md deleted file mode 100644 index 4ebe277..0000000 --- a/generated/prod/docs/tenant_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/tenant_params.md b/generated/prod/docs/tenant_params.md deleted file mode 100644 index 4db7d6b..0000000 --- a/generated/prod/docs/tenant_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Parameters - -- [Create params](tenant_params_create.md) -- [Modify params](tenant_params_modify.md) diff --git a/generated/prod/docs/tenant_params_create.md b/generated/prod/docs/tenant_params_create.md deleted file mode 100644 index 10d4d27..0000000 --- a/generated/prod/docs/tenant_params_create.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
239grafana_org_namestringWZ-Код клиентаregex=^WZ[\d]+$
240resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/prod/docs/tenant_params_modify.md b/generated/prod/docs/tenant_params_modify.md deleted file mode 100644 index cc3e107..0000000 --- a/generated/prod/docs/tenant_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/valo_tenant.md b/generated/prod/docs/valo_tenant.md deleted file mode 100644 index 6860e2f..0000000 --- a/generated/prod/docs/valo_tenant.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## MAN - -
-# Инструкция по развертыванию Тенант Valo через платформу

## 1. Общая информация
Тенант Valo — логический изолированный экземпляр сервиса VALO Cloud, предоставляющий защищённое облачное хранилище, синхронизацию данных и доступ к документам с различных устройств. При создании тенант автоматически разворачивается в тестовом режиме сроком на 2 месяца. Перевод в промышленную эксплуатацию выполняется отдельной операцией.

### Доступные операции

* **create** — создание нового тенанта в тестовом режиме сроком на 2 месяца.
* **modify** — изменение настроек тенанта, включая перевод из ТЕСТ в ПРОД.
* **suspend** — выключение (приостановка работы) тенанта.
* **resume** — включение ранее приостановленного тенанта.
* **delete** — удаление тенанта; доступно только после выполнения операции suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создан тенант.
Пример значения: `valo.ngcloud.ru`.

### DNS-Префикс
Описание: Будет добавлено в зону valo.ngcloud.ru
Пример значения: `mysimpledomain`.

### Параметры хранилища
Описание: Сколько места будет выделено под использование в тенанте. Данные хранятся в S3. Размер указывается в Gigabytes
Пример значения: `10`.

### Настройки тенанта
Описание: Ряд конфигурации Valo-тенанта, такие как настройки пользователя и доступного функционала
Пример значения: `опционально в рамках настройки`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
Достаточно развернуть тенант в ТЕСТ. Срок предоставляется в 2 месяца. По истечению срока тенант автоматически переводится в `suspend` на стороне ресурсной платформы

### Промышленное окружение
Для разблокировки используйте операцию `modify`

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Статус тенанта
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация
Тенант всегда создаётся в режиме ТЕСТ и не может быть сразу переведён в ПРОД без операции modify.
Удаление тенанта возможно только после его выключения с помощью операции suspend.
Срок тестового режима составляет 2 месяца с момента создания.
Операции suspend и resume используются для временного управления доступностью сервиса без потери конфигурации.
-
diff --git a/generated/prod/docs/valo_tenant_example.md b/generated/prod/docs/valo_tenant_example.md deleted file mode 100644 index 44a3695..0000000 --- a/generated/prod/docs/valo_tenant_example.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Copy-ready manifest (`valo_tenant_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_valo_tenant" "baza" { - resource_realm = "TODO" - domain = "TODO" # Будет добавлено в зону valo.ngcloud.ru - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - valo_options = {} - s3_storage = 10 # Параметр указывается в `Gb` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_valo_tenant.baza.state_params["имя_ключа"] -nubes_valo_tenant.baza.state_out["имя_ключа"] -nubes_valo_tenant.baza.state_params_flat["имя_ключа"] -nubes_valo_tenant.baza.state_out_flat["имя_ключа"] -nubes_valo_tenant.baza.vault_secrets["имя_ключа"] -nubes_valo_tenant.baza.vault_url -nubes_valo_tenant.baza.vault_user_path -nubes_valo_tenant.baza.vault_fields -``` diff --git a/generated/prod/docs/valo_tenant_ops.md b/generated/prod/docs/valo_tenant_ops.md deleted file mode 100644 index 89cb168..0000000 --- a/generated/prod/docs/valo_tenant_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](valo_tenant_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](valo_tenant_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/valo_tenant_outputs.md b/generated/prod/docs/valo_tenant_outputs.md deleted file mode 100644 index 2d4ea5d..0000000 --- a/generated/prod/docs/valo_tenant_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/valo_tenant_params.md b/generated/prod/docs/valo_tenant_params.md deleted file mode 100644 index 2c3d14f..0000000 --- a/generated/prod/docs/valo_tenant_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Parameters - -- [Create params](valo_tenant_params_create.md) -- [Modify params](valo_tenant_params_modify.md) diff --git a/generated/prod/docs/valo_tenant_params_create.md b/generated/prod/docs/valo_tenant_params_create.md deleted file mode 100644 index a0e9538..0000000 --- a/generated/prod/docs/valo_tenant_params_create.md +++ /dev/null @@ -1,38 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
655resource_realmstringfunc=getAvailableResourceRealms
656domainstringБудет добавлено в зону valo.ngcloud.ruregex=^[a-z0-9](?:[a-z0-9-]{3,61}[a-z0-9])?$; maxlength=61; minlength=3
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
657valo_optionsmap-fixed{}
658s3_storageinteger10Данные хранятся в отдельном экземпляре S3minvalue=1; maxvalue=999
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/valo_tenant_params_modify.md b/generated/prod/docs/valo_tenant_params_modify.md deleted file mode 100644 index 4b07bec..0000000 --- a/generated/prod/docs/valo_tenant_params_modify.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Modify params - - - - - - -
IDCodeTypeDescriptionConstraints
659valo_optionsmap-fixed
660s3_storageintegerДанные хранятся в отдельном экземпляре S3
diff --git a/generated/prod/docs/vapp.md b/generated/prod/docs/vapp.md deleted file mode 100644 index 630f47c..0000000 --- a/generated/prod/docs/vapp.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## MAN - -
-# Инструкция по развертыванию Виртуальный каталог ВМ (vApp) через платформу

## 1. Общая информация

**Виртуальный каталог ВМ (vApp)** — это логическая каталог, объединённая в единый управляемый объект. Сервис предназначен для совместного развертывания, управления жизненным циклом и сетевого взаимодействия набора связанных ВМ. Основные функции включают:
- централизованное управление включением, выключением и приостановкой группы ВМ;
- унифицированный сетевой доступ через привязанный Edge-шлюз;

### Доступные операции

**create** — Создание нового vApp с привязкой к заданным услугам VDC и Edge
**delete** — Удаление существующего vApp. Требуется предварительный перевод vApp в состояние *suspend*. Полное удаление возможно через 14 дней.
**suspend** — Остановка vApp (выключение всех ВМ внутри каталога)
**resume** — Запуск vApp (включение всех ВМ внутри каталога)

---

## 2. Параметры развертывания

Параметры берутся из операции **create**.

### UUID Услуги VDC
Уникальный идентификатор услуги «Виртуальный датацентр (vDC)».
Используется для определения вычислительной инфраструктуры, в которой будет развернут vApp.

### UUID Услуги Edge
Уникальный идентификатор услуги «Сетевой шлюз периметра (Edge)».
Обеспечивает маршрутизацию и сетевое подключение. Может быть привязан к группе VDC, поэтому выбирается отдельно.

### Имя vApp
Строгое имя, соответствующее маске формирования DNS-имени.
Используется как часть в DNS-имени при создании виртуальных машин.

---

## 3. Рекомендованные характеристики
Так как является промежуточным этапом для создания ВМ, все характеристики описываются в услуге `Виртуальная машина`

---

## 4. Выходные параметры

### Параметры vApp
Заданные при создании vApp

---

## 5. Дополнительная информация

- Привязка к VDC и Edge осуществляется раздельно, поскольку один Edge может обслуживать несколько VDC (через услугу `Группа виртуальных датацентров (groupvDC)`). Это гарантирует возможность развернуть ВМ в единой сети, но в разных виртуальных датацентрах.
- Перед удалением vApp необходимо вручную перевести его в состояние **suspend**. Удаление возможно только спустя 14 дней после этого шага.
- Операция delete удаляет весь vApp полностью, включая все виртуальные машины, связанные с ним.
- Рекомендуется заранее планировать сетевые связи и назначения DNS-имён для обеспечения корректной работы сервисов, развернутых внутри vApp.
- При проектировании инфраструктуры следует учитывать зависимости между Edge-шлюзом, VDC и размещаемыми ВМ, чтобы избежать ограничений при масштабировании и интеграции. -
diff --git a/generated/prod/docs/vapp_example.md b/generated/prod/docs/vapp_example.md deleted file mode 100644 index 0400883..0000000 --- a/generated/prod/docs/vapp_example.md +++ /dev/null @@ -1,45 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Copy-ready manifest (`vapp_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vapp" "baza" { - nsxt_uid = "TODO" # UUID Услуги `Сетевой шлюз периметра (Edge)` - vapp_name = "TODO" # Уникальное в рамках организации - vdc_uid = "TODO" # UUID Услуги `Виртуальный датацентр (vDC)` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vapp.baza.state_params["имя_ключа"] -nubes_vapp.baza.state_out["имя_ключа"] -nubes_vapp.baza.state_params_flat["имя_ключа"] -nubes_vapp.baza.state_out_flat["имя_ключа"] -nubes_vapp.baza.vault_secrets["имя_ключа"] -nubes_vapp.baza.vault_url -nubes_vapp.baza.vault_user_path -nubes_vapp.baza.vault_fields -``` diff --git a/generated/prod/docs/vapp_ops.md b/generated/prod/docs/vapp_ops.md deleted file mode 100644 index 5e1eba0..0000000 --- a/generated/prod/docs/vapp_ops.md +++ /dev/null @@ -1,14 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vapp_params_create.md) -- `delete` -- `resume` -- `suspend` diff --git a/generated/prod/docs/vapp_outputs.md b/generated/prod/docs/vapp_outputs.md deleted file mode 100644 index 0ff0f8e..0000000 --- a/generated/prod/docs/vapp_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/vapp_params.md b/generated/prod/docs/vapp_params.md deleted file mode 100644 index 4c7addc..0000000 --- a/generated/prod/docs/vapp_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Parameters - -- [Create params](vapp_params_create.md) -- [Modify params](vapp_params_modify.md) diff --git a/generated/prod/docs/vapp_params_create.md b/generated/prod/docs/vapp_params_create.md deleted file mode 100644 index 3b23cff..0000000 --- a/generated/prod/docs/vapp_params_create.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
190nsxt_uiduuidК какой сети может быть подключен виртуальный каталогref_svc_id=22
191vapp_namestringИмеет строгую маску `^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$`

Используется в формировании DNS-Имени (для виртуальных машин)
regex=^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$; minlength=3
623vdc_uiduuidВ каких ресурсах будет создан виртуальный каталогref_svc_id=21
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/vapp_params_modify.md b/generated/prod/docs/vapp_params_modify.md deleted file mode 100644 index 4fca747..0000000 --- a/generated/prod/docs/vapp_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/vc_complex.md b/generated/prod/docs/vc_complex.md deleted file mode 100644 index c83cece..0000000 --- a/generated/prod/docs/vc_complex.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## MAN - -
-# Создает окружение для ВМ.

## Создает сервисы:
**Организация**
**Виртуальный датацентр**
**Каталог**
**Сетевой шлюз периметра**

-
diff --git a/generated/prod/docs/vc_complex_example.md b/generated/prod/docs/vc_complex_example.md deleted file mode 100644 index 56a54ba..0000000 --- a/generated/prod/docs/vc_complex_example.md +++ /dev/null @@ -1,59 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Copy-ready manifest (`vc_complex_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_complex" "baza" { - resource_realm = "TODO" # Платформа для развертывания - vapp_name = "TODO" # Имя vApp - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - vdc_provider_gateway = "sandbox-v1cl1-pvdc" # Взять из свойств ресурсной платформы. Путь .vcd.providerVdc - взять KEY providerGateway Cloud Director. Влияет ресурсы будут предоставлены. Является полем (List) в свойствах рес. платформы ЛК, но сам параметр передаётся только как один String - virtual_services_count = 1 # Кол-во виртуальных сервисов, которые выделяются на AVI. Во избежании коллапса пока выделяется до 4 - ip_space_name = "internet-ipv4-v1" # Имя ip Space для внешнего IP. Целесообразнее брать самый дешёвый, так как это vip для исходящего трафика. Необходимо задавать если включен needExternalAddressSNAT - storage_config = [{"name": "", "size": 1024}] # Описывается как массив объектов, где описывается имя политики и её размер - vdc_network_pool = "nsxt-sandbox-geneve-np" - cpu_guaranteed = 20 - mem_guaranteed = 20 - segroup_name = "SEGROUP-SANDBOX-CL1-SHARED-01" # Наименование segroup, в котором будут выделяться пулы на AVI - need_external_address_snat = true # Выделяет внешний IP на Edge. Используется для SNAT всего трафика - need_enable_avi = false # Включает AVI в Cloud Director - cpu_allocated = 1 # шт - mem_allocated = 10 # gb - v_ipcount = 0 # ш -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_complex.baza.state_params["имя_ключа"] -nubes_vc_complex.baza.state_out["имя_ключа"] -nubes_vc_complex.baza.state_params_flat["имя_ключа"] -nubes_vc_complex.baza.state_out_flat["имя_ключа"] -nubes_vc_complex.baza.vault_secrets["имя_ключа"] -nubes_vc_complex.baza.vault_url -nubes_vc_complex.baza.vault_user_path -nubes_vc_complex.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_complex_ops.md b/generated/prod/docs/vc_complex_ops.md deleted file mode 100644 index 9d016bc..0000000 --- a/generated/prod/docs/vc_complex_ops.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_complex_params_create.md) diff --git a/generated/prod/docs/vc_complex_outputs.md b/generated/prod/docs/vc_complex_outputs.md deleted file mode 100644 index 629a059..0000000 --- a/generated/prod/docs/vc_complex_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/vc_complex_params.md b/generated/prod/docs/vc_complex_params.md deleted file mode 100644 index 82b3c13..0000000 --- a/generated/prod/docs/vc_complex_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Parameters - -- [Create params](vc_complex_params_create.md) -- [Modify params](vc_complex_params_modify.md) diff --git a/generated/prod/docs/vc_complex_params_create.md b/generated/prod/docs/vc_complex_params_create.md deleted file mode 100644 index 6b0b9ec..0000000 --- a/generated/prod/docs/vc_complex_params_create.md +++ /dev/null @@ -1,37 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
332resource_realmstringНаименование ресурсной платформыfunc=getAvailableResourceRealms
334vapp_namestringИмя vAppregex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
358vdc_provider_gatewaystringsandbox-v1cl1-pvdcВзять из свойств ресурсной платформы.
Путь .vcd.providerVdc - взять KEY

providerGateway Cloud Director. Влияет ресурсы будут предоставлены. Является полем (List&lt;String&gt;) в свойствах рес. платформы ЛК, но сам параметр передаётся только как один String
359virtual_services_count1Кол-во виртуальных сервисов, которые выделяются на AVI. Во избежании коллапса пока выделяется до 4minvalue=1; maxvalue=4
360ip_space_namestringinternet-ipv4-v1Имя ip Space для внешнего IP. Целесообразнее брать самый дешёвый, так как это vip для исходящего трафика. Необходимо задавать если включен needExternalAddressSNAT
399storage_configjson[{"name": "", "size": 1024}]Описывается как массив объектов, где описывается имя политики и её размер
400vdc_network_poolstringnsxt-sandbox-geneve-np
401cpu_guaranteedinteger20value_list=20, 50, 80
402mem_guaranteedinteger20value_list=20, 50, 80
403segroup_namestringSEGROUP-SANDBOX-CL1-SHARED-01Наименование segroup, в котором будут выделяться пулы на AVI
404need_external_address_snatbooleantrueВыделяет внешний IP на Edge. Используется для SNAT всего трафикаvalue_list=false, true
405need_enable_avibooleanfalseВключает AVI в Cloud Directorvalue_list=false, true
566cpu_allocatedstring1штminvalue=1
567mem_allocatedinteger10gbminvalue=1
568v_ipcountinteger0шminvalue=0; maxvalue=20
diff --git a/generated/prod/docs/vc_complex_params_modify.md b/generated/prod/docs/vc_complex_params_modify.md deleted file mode 100644 index b6a1be3..0000000 --- a/generated/prod/docs/vc_complex_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/vc_nsxt.md b/generated/prod/docs/vc_nsxt.md deleted file mode 100644 index 0c8056d..0000000 --- a/generated/prod/docs/vc_nsxt.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## MAN - -
-# Инструкция по развертыванию Сетевой шлюз периметра (Edge) через платформу

## 1. Общая информация

Сервис **Сетевой шлюз периметра (Edge)** предназначен для создания периметрового сетевого шлюза в рамках одного виртуального датацентра (vDC) или группы виртуальных датацентров (groupvDC).
При создании автоматически разворачивается routed-сеть с адресным пространством `10.10.102.0/24`.
Сервис обеспечивает сетевую изоляцию, маршрутизацию, а также может включать функциональность балансировщика нагрузки AVI (ALB) для последующей интеграции, включая поддержку кластеров Штурвал.

### Доступные операции

**create** — Создание нового Edge с привязкой к vDC или groupvDC и развёртыванием routed-сети.
**delete** — Удаление ранее созданного Edge. Недоступно при наличии зависимых услуг (vApp, VM, Кластер Штурвал).
**modify** — Изменение параметров и сетевых настроек существующего Edge.

---

## 2. Параметры развертывания

Ниже приведены параметры операции **create**.

### Тип родительской услуги
Определяет контекст размещения Edge.
Допустимые значения: `vdc`, `groupvdc`.
Использование:
- При выборе `vdc` обязателен параметр **UUID VDC**.
- При выборе `groupvdc` обязателен параметр **UUID Группы VDC**.

### UUID VDC
Идентификатор виртуального датацентра.
Необходимо предварительно создать vDC через услугу «Виртуальный датацентр (vDC)».
Указывается только при выборе родительского типа `vdc`.

### UUID Группы VDC
Идентификатор группы виртуальных датацентров.
Создаётся через услугу «Группа виртуальных датацентров (groupvDC)».
Используется при выборе родительского типа `groupvdc`.

### Включить ALB
Флаг активации AVI Load Balancer в Cloud Director.
Пример значения: `true`/`false`.
Нужен для развёртывания кластера Штурвал и возможности создания Virtual Services.

### Наименование segroup
Имя сервиса групп (segroup) на уровне ресурсной платформы.
Обязательно при включённом ALB.
Определяет группу, в которой будут выделяться пулы AVI для Virtual Services.

### virtualServicesCount
Количество резервируемых виртуальных сервисов (Virtual Services) на AVI.
Типичное значение: 1–10 в зависимости от нагрузки.

---

## 3. Рекомендованные характеристики

### Тестовое окружение (Test)

- Тип родительской услуги: `vdc`
- virtualServicesCount: 1–2
- ALB: выключен по умолчанию (включать только при необходимости тестирования Штурвала)
- segroup: задаётся только при включённом ALB
- VDC гарантии CPU/RAM: минимальные (поскольку изменить их после создания нельзя)

### Промышленное окружение (Production)

- Тип родительской услуги: `groupvdc` при работе с распределёнными нагрузками или `vdc` для локализованных проектов
- virtualServicesCount: 3–10, исходя из предполагаемого количества публикаций
- ALB: включён, если требуется высокая доступность сервисов или используется кластер Штурвал
- segroup: рекомендуется использовать выделенную группу под проект
- VDC гарантии CPU/RAM: повышенные, с учётом того, что изменить их после создания невозможно без пересоздания vDC

---

## 4. Выходные параметры

### Имя Edge
Уникальное название созданного сетевого шлюза, используется для ссылок и дальнейших операций.

### Имя routed-сети
Автоматически созданная routed-сеть с подсетью `10.10.102.0/24`, используется для подключения ресурсов.

### Параметры Edge
Набор параметров, указанных пользователем при создании: тип услуги, ALB, segroup, virtualServicesCount и др.
Используются в операциях modify и для анализа состояния сервиса.

---

## 5. Дополнительная информация

- В рамках сервиса **один раз при создании задаётся гарантированная доля CPU/RAM vDC**. Изменить её невозможно — требуется пересоздание vDC.
- Удаление Edge недоступно при наличии зависимых ресурсов (vApp, VM, кластер Штурвал).
- При использовании ALB необходимо корректно указывать segroup, чтобы обеспечить корректное выделение пулов AVI.
- При выборе режима `groupvdc` следует учитывать распределение нагрузки между несколькими vDC.
- SNAT для всех ресурсов внутри Edge можно активировать через операцию modify (параметры выделения VIP и ipSpace).

-
diff --git a/generated/prod/docs/vc_nsxt_example.md b/generated/prod/docs/vc_nsxt_example.md deleted file mode 100644 index 8e0a04f..0000000 --- a/generated/prod/docs/vc_nsxt_example.md +++ /dev/null @@ -1,47 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Copy-ready manifest (`vc_nsxt_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_nsxt" "baza" { - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - need_enable_avi = false # Включение Load Balancer - virtual_services_count = 1 # Кол-во виртуальных сервисов, которые выделяются на AVI - vdc_type = "vdc" # Тип родительской услуги -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_nsxt.baza.state_params["имя_ключа"] -nubes_vc_nsxt.baza.state_out["имя_ключа"] -nubes_vc_nsxt.baza.state_params_flat["имя_ключа"] -nubes_vc_nsxt.baza.state_out_flat["имя_ключа"] -nubes_vc_nsxt.baza.vault_secrets["имя_ключа"] -nubes_vc_nsxt.baza.vault_url -nubes_vc_nsxt.baza.vault_user_path -nubes_vc_nsxt.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_nsxt_ops.md b/generated/prod/docs/vc_nsxt_ops.md deleted file mode 100644 index 03af84f..0000000 --- a/generated/prod/docs/vc_nsxt_ops.md +++ /dev/null @@ -1,14 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_nsxt_params_create.md) -- `delete` — Невозможно удалить если routed-сеть в Edge связана с: - vApp - VM - Kubernetes-кластер Штурвал Запустить операцию возможно, но будет ошибка -- `modify` — Изменение кластера. Параметры: [Modify params](vc_nsxt_params_modify.md) -- `reconcile` diff --git a/generated/prod/docs/vc_nsxt_outputs.md b/generated/prod/docs/vc_nsxt_outputs.md deleted file mode 100644 index 717cbc4..0000000 --- a/generated/prod/docs/vc_nsxt_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/vc_nsxt_params.md b/generated/prod/docs/vc_nsxt_params.md deleted file mode 100644 index 2cf1cc1..0000000 --- a/generated/prod/docs/vc_nsxt_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Parameters - -- [Create params](vc_nsxt_params_create.md) -- [Modify params](vc_nsxt_params_modify.md) diff --git a/generated/prod/docs/vc_nsxt_params_create.md b/generated/prod/docs/vc_nsxt_params_create.md deleted file mode 100644 index 9f77ac0..0000000 --- a/generated/prod/docs/vc_nsxt_params_create.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
8vdc_uidstringНеобходимо, если выбран тип подключаемой VDC: `vdc`ref_svc_id=21
622vdc_group_uidstringНеобходимо, если выбран тип подключаемой VDC: `groupvdc`ref_svc_id=29
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
340need_enable_avibooleanfalseПараметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указатьvalue_list=false, true
341virtual_services_countinteger1Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB`
minvalue=1; maxvalue=4
621vdc_typestringvdcПри выборе vdc обеспечивает сетевую доступность только в рамках этого vdc
При выборе groupvdc обеспечивает сетевую доступность между всеми vdc, которые включены в groupvdc
value_list=vdc, vdcGroup
diff --git a/generated/prod/docs/vc_nsxt_params_modify.md b/generated/prod/docs/vc_nsxt_params_modify.md deleted file mode 100644 index 0a1fc0e..0000000 --- a/generated/prod/docs/vc_nsxt_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
368need_enable_avibooleanПараметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указатьvalue_list=false, true
369virtual_services_countintegerВо избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB`
minvalue=1; maxvalue=4
371need_external_address_snatbooleanПараметр `ip Space для VIP` станет обязательным, если указан `true`value_list=false, true
372ip_space_namestringНеобходимо указывать, если включён параметр `Выделить VIP для SNAT`
diff --git a/generated/prod/docs/vc_org.md b/generated/prod/docs/vc_org.md deleted file mode 100644 index e500201..0000000 --- a/generated/prod/docs/vc_org.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## MAN - -
-# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Url организации
Для быстрого доступа в тенант

### Статус организации
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)** привязанный к этой организации;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к vdc выше.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak. -
diff --git a/generated/prod/docs/vc_org_example.md b/generated/prod/docs/vc_org_example.md deleted file mode 100644 index 5785a4a..0000000 --- a/generated/prod/docs/vc_org_example.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Copy-ready manifest (`vc_org_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_org" "baza" { - resource_realm = "TODO" # Облако в котором будет развёрнут тенант - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - organization_type = "iaas" # Доступ к организации предоставляется только при выборе `iaas` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_org.baza.state_params["имя_ключа"] -nubes_vc_org.baza.state_out["имя_ключа"] -nubes_vc_org.baza.state_params_flat["имя_ключа"] -nubes_vc_org.baza.state_out_flat["имя_ключа"] -nubes_vc_org.baza.vault_secrets["имя_ключа"] -nubes_vc_org.baza.vault_url -nubes_vc_org.baza.vault_user_path -nubes_vc_org.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_org_ops.md b/generated/prod/docs/vc_org_ops.md deleted file mode 100644 index a0c2067..0000000 --- a/generated/prod/docs/vc_org_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_org_params_create.md) -- `delete` — Удалить возможно только через 14 дней после выполнения операции `suspend` **ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого тенанта** Если существуют инстансы VDC, Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов -- `modify` — Изменение кластера. Параметры: [Modify params](vc_org_params_modify.md) -- `reconcile` -- `resume` -- `suspend` — Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри тенанта diff --git a/generated/prod/docs/vc_org_outputs.md b/generated/prod/docs/vc_org_outputs.md deleted file mode 100644 index 9de11b9..0000000 --- a/generated/prod/docs/vc_org_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["urlConnect"]` - diff --git a/generated/prod/docs/vc_org_params.md b/generated/prod/docs/vc_org_params.md deleted file mode 100644 index e187b07..0000000 --- a/generated/prod/docs/vc_org_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Parameters - -- [Create params](vc_org_params_create.md) -- [Modify params](vc_org_params_modify.md) diff --git a/generated/prod/docs/vc_org_params_create.md b/generated/prod/docs/vc_org_params_create.md deleted file mode 100644 index 28f12f0..0000000 --- a/generated/prod/docs/vc_org_params_create.md +++ /dev/null @@ -1,36 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
418resource_realmstringВыбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы
func=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
556organization_typestringiaasДоступ к организации предоставляется только при выборе `iaas`value_list=iaas, saas
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/vc_org_params_modify.md b/generated/prod/docs/vc_org_params_modify.md deleted file mode 100644 index 4142f72..0000000 --- a/generated/prod/docs/vc_org_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
662v_ipconfigurearray-map-fixed
diff --git a/generated/prod/docs/vc_org_saas.md b/generated/prod/docs/vc_org_saas.md deleted file mode 100644 index 95ae27c..0000000 --- a/generated/prod/docs/vc_org_saas.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## MAN - -
-Верхнеуровневая сущность создаваемая для Заказчика.
Внутри Организация вы можете создать: Виртуальные датацентры, Каталоги. -
diff --git a/generated/prod/docs/vc_org_saas_example.md b/generated/prod/docs/vc_org_saas_example.md deleted file mode 100644 index a531fe9..0000000 --- a/generated/prod/docs/vc_org_saas_example.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Copy-ready manifest (`vc_org_saas_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_org_saas" "baza" { - resource_realm = "TODO" # Платформа для развертывания -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_org_saas.baza.state_params["имя_ключа"] -nubes_vc_org_saas.baza.state_out["имя_ключа"] -nubes_vc_org_saas.baza.state_params_flat["имя_ключа"] -nubes_vc_org_saas.baza.state_out_flat["имя_ключа"] -nubes_vc_org_saas.baza.vault_secrets["имя_ключа"] -nubes_vc_org_saas.baza.vault_url -nubes_vc_org_saas.baza.vault_user_path -nubes_vc_org_saas.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_org_saas_ops.md b/generated/prod/docs/vc_org_saas_ops.md deleted file mode 100644 index bcc4618..0000000 --- a/generated/prod/docs/vc_org_saas_ops.md +++ /dev/null @@ -1,14 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_org_saas_params_create.md) -- `delete` -- `resume` -- `suspend` diff --git a/generated/prod/docs/vc_org_saas_outputs.md b/generated/prod/docs/vc_org_saas_outputs.md deleted file mode 100644 index 15052c9..0000000 --- a/generated/prod/docs/vc_org_saas_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/vc_org_saas_params.md b/generated/prod/docs/vc_org_saas_params.md deleted file mode 100644 index a9c08f3..0000000 --- a/generated/prod/docs/vc_org_saas_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Parameters - -- [Create params](vc_org_saas_params_create.md) -- [Modify params](vc_org_saas_params_modify.md) diff --git a/generated/prod/docs/vc_org_saas_params_create.md b/generated/prod/docs/vc_org_saas_params_create.md deleted file mode 100644 index d73866d..0000000 --- a/generated/prod/docs/vc_org_saas_params_create.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
185resource_realmstringНаименование ресурсной платформыfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/vc_org_saas_params_modify.md b/generated/prod/docs/vc_org_saas_params_modify.md deleted file mode 100644 index ad45c99..0000000 --- a/generated/prod/docs/vc_org_saas_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/vc_vdc.md b/generated/prod/docs/vc_vdc.md deleted file mode 100644 index 2d8fa57..0000000 --- a/generated/prod/docs/vc_vdc.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## MAN - -
-# Инструкция по развертыванию Виртуальный датацентр (vDC) через платформу

## 1. Общая информация

**Виртуальный датацентр (vDC)** — это логическая изолированная среда в VMware Cloud Director, предназначенная для размещения и управления виртуальными машинами, сетевой инфраструктурой и ресурсами хранения. Сервис обеспечивает выделение вычислительных ресурсов под конкретную организацию и предоставляет гибкие параметры масштабирования, контроля потребления и разделения ресурсов.

### Доступные операции

**create** — Создание виртуального датацентра (vDC) с заданными параметрами CPU, RAM, Storage и сетевой конфигурацией.
**delete** — Удаление vDC. Требуется предварительный перевод vDC в состояние *suspend*. Полное удаление возможно через 14 дней.
**modify** — Внесение изменений в параметры ресурсов (CPU/RAM/Storage), выделенных для vDC.
**suspend** — Заморозка vDC. Новые ресурсы или изменения внутри vDC становятся невозможными, работа ВМ не останавливается.
**resume** — Разморозка vDC. Восстановление возможности управления сущностями внутри vDC.

---

## 2. Параметры развертывания

Ниже перечислены входные параметры операции **create**.

### UUID Организации
Уникальный идентификатор организации в Cloud Director. Перед созданием vDC требуется предварительное создание услугу `Организация в Cloud Director`.

### Provider VDC в Cloud Director
Свойство ресурсной платформы, определяющее, какой пул физических ресурсов будет использоваться.

### Network Pool в Cloud Director
Определяет возможности сетевой конфигурации, включая создание Edge Gateway и выход во внешние сети.

### Гарантированная доля ЯДЕР
Гарантированный процент вычислительных ресурсов (CPU), закрепленный за vDC. Значение устанавливается разово при создании.

### Гарантированная доля ОЗУ
Гарантированный процент оперативной памяти, закрепленный за vDC. Также задаётся один раз при создании.

### Сколько аллоцировать на VDC ЯДЕР
Количество виртуальных ядер, выделяемых в рамках vDC.

### Сколько аллоцировать на VDC ОЗУ
Количество оперативной памяти в GB, выделяемой для vDC.

### Конфигурация Storage
Набор дисковых политик и их объёмов, выделяемых для vDC. Указывается имя политики и требуемый размер (GB).

---

## 3. Рекомендованные характеристики

### Тестовое окружение

- Количество ядер CPU: 10–20
- Аллоцируемая RAM: 16–64 GB
- Гарантированная доля CPU: 20%
- Гарантированная доля RAM: 20%
- Storage:
- Политика `SATA`
- Объём: 100–300 GB

### Промышленное окружение

- Количество ядер CPU: 16–128
- Аллоцируемая RAM: 64–512 GB
- Гарантированная доля CPU: 50%
- Гарантированная доля RAM: 50%
- Storage:
- Политики уровня `SSD`
- Объём: 1–10 TB, выбор несколько политик под разные нагрузки

---

## 4. Выходные параметры

Выходные параметры формируются операцией **create** (и используются другими операциями):

### Имя vDC
Уникальный идентификатор созданного виртуального датацентра. Используется в дальнейших операциях (modify, suspend, delete).

### Параметры выделенных ресурсов
Подтверждение итогового объёма CPU/RAM/Storage, выделенных vDC. Используются для учёта и контроля потребления.

---

## 5. Дополнительная информация

- Перед созданием vDC необходимо обеспечить наличие корректно созданной организации и доступных пула ресурсов ресурсной платформы.
- Гарантированная доля CPU и RAM задаётся **однократно при создании vDC**. После развертывания изменить эти значения невозможно; для изменения необходимо пересоздать vDC.
- Удаление vDC возможно только через **14 дней после перевода в состояние *suspend***. Удаление очищает все связанные сущности (ВМ, сети, каталоги), поэтому необходимо убедиться, что данные перенесены.
- Платформа Cloud Director использует концепцию изолированных организационных ресурсов, поэтому корректная настройка Provider VDC и Network Pool является обязательной при создании vDC.
- При изменении параметров (modify) изменяются только показатели CPU, RAM и Storage. Сетевые параметры и гарантированные доли остаются неизменными.
-
diff --git a/generated/prod/docs/vc_vdc_example.md b/generated/prod/docs/vc_vdc_example.md deleted file mode 100644 index 7b6e1bc..0000000 --- a/generated/prod/docs/vc_vdc_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Copy-ready manifest (`vc_vdc_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_vdc" "baza" { - organization_uid = "TODO" # Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` - provider_vdc = "TODO" # Приписка `2.8` - Скорость vCPU - 2800MHz И так далее... - storage_config = "TODO" # Первая политика в списке указывается как "По умолчанию" - network_provider = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - cpu_guaranteed = 20 # % резервирования - mem_guaranteed = 20 # % резервирования - cpu_allocated = 10 # шт - mem_allocated = 20 # gb -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vdc.baza.state_params["имя_ключа"] -nubes_vc_vdc.baza.state_out["имя_ключа"] -nubes_vc_vdc.baza.state_params_flat["имя_ключа"] -nubes_vc_vdc.baza.state_out_flat["имя_ключа"] -nubes_vc_vdc.baza.vault_secrets["имя_ключа"] -nubes_vc_vdc.baza.vault_url -nubes_vc_vdc.baza.vault_user_path -nubes_vc_vdc.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_vdc_group.md b/generated/prod/docs/vc_vdc_group.md deleted file mode 100644 index 1ff3cd6..0000000 --- a/generated/prod/docs/vc_vdc_group.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## MAN - -
-# Инструкция по развертыванию Группа виртуальных датацентров (groupvDC) через платформу

## 1. Общая информация

Сервис **Группа виртуальных датацентров (groupvDC)** предназначен для логического объединения нескольких виртуальных датацентров (vDC) в единую группу. Это позволяет растягивать SDN между разными vDC и централизованно управлять сетевой связностью. Управление инфраструктурой осуществляется через Cloud Director.
Сервис применяется в случаях, когда требуется обеспечить единое сетевое пространство для распределенных виртуальных датацентров.

### Доступные операции

**create** — Создание новой группы виртуальных датацентров.
**delete** — Удаление существующей группы vDC.
**add_vdc** — Добавление дополнительного виртуального датацентра в группу.
**remove_vdc** — Удаление ранее добавленного виртуального датацентра из группы.

---

## 2. Параметры развертывания

Параметры операции **create**:

### UUID VDC
Идентификатор виртуального датацентра, который будет являться первичным в группе.
Описание: требуется предварительно создать виртуальный датацентр с помощью услуги `Виртуальный датацентр (vDC)`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Для тестового окружения создавать группу VDC нет необходимости, так как это создаёт дополнительный слой абстракции в Cloud Director

### Промышленное окружение
- Для промышленного окружения, если в тенанте существуют разные VDC, создание groupvdc позволит снизить сетевые издержки (за счёт общей сети)

---

## 4. Выходные параметры

### Параметры groupvdc
Набор параметров, указанных пользователем при создании

---

## 5. Дополнительная информация
- Группа vDC используется для растягивания SDN между несколькими виртуальными датацентрами. Управление всеми сетевыми элементами внутри группы выполняется Cloud Director.
- Удалить первичный vDC (тот, что был указан при операции **create**) невозможно. Для его удаления необходимо удалить всю группу и создать новую.
- Перед добавлением любого vDC в группу он должен быть предварительно развернут через сервис `Виртуальный датацентр (vDC)`.
- Сети создаются не в этой услуге, а в услуге `Сетевой шлюз периметра (Edge)`. В ней необходимо будет выбрать тип `groupvdc` -
diff --git a/generated/prod/docs/vc_vdc_group_example.md b/generated/prod/docs/vc_vdc_group_example.md deleted file mode 100644 index 0fecefd..0000000 --- a/generated/prod/docs/vc_vdc_group_example.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Copy-ready manifest (`vc_vdc_group_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_vdc_group" "baza" { - vdc_uid = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vdc_group.baza.state_params["имя_ключа"] -nubes_vc_vdc_group.baza.state_out["имя_ключа"] -nubes_vc_vdc_group.baza.state_params_flat["имя_ключа"] -nubes_vc_vdc_group.baza.state_out_flat["имя_ключа"] -nubes_vc_vdc_group.baza.vault_secrets["имя_ключа"] -nubes_vc_vdc_group.baza.vault_url -nubes_vc_vdc_group.baza.vault_user_path -nubes_vc_vdc_group.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_vdc_group_ops.md b/generated/prod/docs/vc_vdc_group_ops.md deleted file mode 100644 index 9552c15..0000000 --- a/generated/prod/docs/vc_vdc_group_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Operations - -- `add_vdc` — **Не нужно** выбирать UUID VDC, который уже был добавлен в группу -- `create` — Создание кластера. Параметры: [Create params](vc_vdc_group_params_create.md) -- `delete` -- `reconcile` -- `remove_vdc` diff --git a/generated/prod/docs/vc_vdc_group_outputs.md b/generated/prod/docs/vc_vdc_group_outputs.md deleted file mode 100644 index 5714cde..0000000 --- a/generated/prod/docs/vc_vdc_group_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/vc_vdc_group_params.md b/generated/prod/docs/vc_vdc_group_params.md deleted file mode 100644 index d292ab9..0000000 --- a/generated/prod/docs/vc_vdc_group_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Parameters - -- [Create params](vc_vdc_group_params_create.md) -- [Modify params](vc_vdc_group_params_modify.md) diff --git a/generated/prod/docs/vc_vdc_group_params_create.md b/generated/prod/docs/vc_vdc_group_params_create.md deleted file mode 100644 index 624e982..0000000 --- a/generated/prod/docs/vc_vdc_group_params_create.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
618vdc_uiduuidref_svc_id=21
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/prod/docs/vc_vdc_group_params_modify.md b/generated/prod/docs/vc_vdc_group_params_modify.md deleted file mode 100644 index 721de57..0000000 --- a/generated/prod/docs/vc_vdc_group_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Modify params - -None. diff --git a/generated/prod/docs/vc_vdc_ops.md b/generated/prod/docs/vc_vdc_ops.md deleted file mode 100644 index b1a1776..0000000 --- a/generated/prod/docs/vc_vdc_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vdc_params_create.md) -- `delete` — Удалить возможно только через 14 дней после выполнения операции `suspend` **ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого VDC** Если существуют инстансы Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vdc_params_modify.md) -- `reconcile` -- `resume` -- `suspend` — Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри VDC diff --git a/generated/prod/docs/vc_vdc_outputs.md b/generated/prod/docs/vc_vdc_outputs.md deleted file mode 100644 index a435292..0000000 --- a/generated/prod/docs/vc_vdc_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["vdcName"]` - diff --git a/generated/prod/docs/vc_vdc_params.md b/generated/prod/docs/vc_vdc_params.md deleted file mode 100644 index 03c0037..0000000 --- a/generated/prod/docs/vc_vdc_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Parameters - -- [Create params](vc_vdc_params_create.md) -- [Modify params](vc_vdc_params_modify.md) diff --git a/generated/prod/docs/vc_vdc_params_create.md b/generated/prod/docs/vc_vdc_params_create.md deleted file mode 100644 index c9e89a7..0000000 --- a/generated/prod/docs/vc_vdc_params_create.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
30organization_uiduuidДля создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director`ref_svc_id=19
335provider_vdcstringПриписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
361storage_configarray-map-fixedПервая политика в списке указывается как &quot;По умолчанию&quot;
746network_providerstring
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
397cpu_guaranteedinteger20Свойство нельзя изменить после созданияvalue_list=20, 50, 80
398mem_guaranteedinteger20После создания нельзя изменитьvalue_list=20, 50, 80
557cpu_allocatedinteger10штminvalue=1; maxvalue=200
558mem_allocatedinteger20gbminvalue=1; maxvalue=4096
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/vc_vdc_params_modify.md b/generated/prod/docs/vc_vdc_params_modify.md deleted file mode 100644 index 4bb0906..0000000 --- a/generated/prod/docs/vc_vdc_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
560cpu_allocatedintegerштminvalue=1; maxvalue=999
561mem_allocatedintegergbminvalue=1; maxvalue=1024
562storage_configarray-map-fixedПервая политика в списке указывается как &quot;По умолчанию&quot;
diff --git a/generated/prod/docs/vc_vm.md b/generated/prod/docs/vc_vm.md deleted file mode 100644 index e0c84ef..0000000 --- a/generated/prod/docs/vc_vm.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## MAN - -
-Виртуальная машина без каких-либо особенностей.
Данная услуга запускает vc_ip для выдачи белого адреса и подключения к ВМ -
diff --git a/generated/prod/docs/vc_vm_example.md b/generated/prod/docs/vc_vm_example.md deleted file mode 100644 index 223d7b0..0000000 --- a/generated/prod/docs/vc_vm_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Copy-ready manifest (`vc_vm_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_vm" "baza" { - vapp_uid = "TODO" # InstanceUid vApp. vApp должен быть создан - ip_space_name = "TODO" # Брать из свойств ресурсной платформы .vcd.ipSpace Имя IP-space для выделения внешнего IP (IP выделяется обязательно) - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - vm_name = "vm0001" # Имя ВМ. Не поддерживает спец-символы - vm_cpu = 2 # CPU - vm_ram = 2 # RAM (GB) - vm_disksize = 10 # Размер диска под сервис (GB) - template_name = "RockyLinux_9-16G" # ОС - access_ip_list = "79.111.119.78/32 185.247.187.1/32" # Вставить содержимое из 'curl ifconfig.io' IP адреса в CIDR формате через пробел для настройки аксес листов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vm.baza.state_params["имя_ключа"] -nubes_vc_vm.baza.state_out["имя_ключа"] -nubes_vc_vm.baza.state_params_flat["имя_ключа"] -nubes_vc_vm.baza.state_out_flat["имя_ключа"] -nubes_vc_vm.baza.vault_secrets["имя_ключа"] -nubes_vc_vm.baza.vault_url -nubes_vc_vm.baza.vault_user_path -nubes_vc_vm.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_vm_ops.md b/generated/prod/docs/vc_vm_ops.md deleted file mode 100644 index ff1e0cf..0000000 --- a/generated/prod/docs/vc_vm_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vm_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vm_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/vc_vm_outputs.md b/generated/prod/docs/vc_vm_outputs.md deleted file mode 100644 index d5163ba..0000000 --- a/generated/prod/docs/vc_vm_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/vc_vm_params.md b/generated/prod/docs/vc_vm_params.md deleted file mode 100644 index 0ff6c3e..0000000 --- a/generated/prod/docs/vc_vm_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Parameters - -- [Create params](vc_vm_params_create.md) -- [Modify params](vc_vm_params_modify.md) diff --git a/generated/prod/docs/vc_vm_params_create.md b/generated/prod/docs/vc_vm_params_create.md deleted file mode 100644 index 5bed0ba..0000000 --- a/generated/prod/docs/vc_vm_params_create.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
33vapp_uiduuidInstanceUid vApp. vApp должен быть созданref_svc_id=26
406ip_space_namestringБрать из свойств ресурсной платформы
.vcd.ipSpace

Имя IP-space для выделения внешнего IP (IP выделяется обязательно)
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
35vm_namestringvm0001Имя ВМ. Не поддерживает спец-символыregex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
36vm_cpustring2CPU
37vm_ramstring2RAM (GB)
38vm_disksizestring10Размер диска под сервис (GB)
176template_namestringRockyLinux_9-16GОСvalue_list=RockyLinux_9-16G, OracleLinux_9-16G, Ubuntu_24-20G, Ubuntu_22-20G
177access_ip_liststring79.111.119.78/32 185.247.187.1/32IP адреса в CIDR формате через пробел для настройки аксес листов
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/vc_vm_params_modify.md b/generated/prod/docs/vc_vm_params_modify.md deleted file mode 100644 index 0ec4505..0000000 --- a/generated/prod/docs/vc_vm_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
186vm_cpuintegerCPU
187vm_ramintegerRAM
188vm_disksizeintegerРазмер диска под сервис (GB)
189access_ip_liststringIP адреса в CIDR формате через пробел для настройки аксес листов
diff --git a/generated/prod/docs/vc_vm_v2.md b/generated/prod/docs/vc_vm_v2.md deleted file mode 100644 index ada3402..0000000 --- a/generated/prod/docs/vc_vm_v2.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/prod/docs/vc_vm_v2_example.md b/generated/prod/docs/vc_vm_v2_example.md deleted file mode 100644 index a22d7c6..0000000 --- a/generated/prod/docs/vc_vm_v2_example.md +++ /dev/null @@ -1,45 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Copy-ready manifest (`vc_vm_v2_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_vm_v2" "baza" { - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - server_list_json = [{}] # Необходимо изменить vappUid и ipSpaceName Пример конфигурации взять по ссылке ниже Объект серверов вида [{}] (Map(Object)) Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2) -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vm_v2.baza.state_params["имя_ключа"] -nubes_vc_vm_v2.baza.state_out["имя_ключа"] -nubes_vc_vm_v2.baza.state_params_flat["имя_ключа"] -nubes_vc_vm_v2.baza.state_out_flat["имя_ключа"] -nubes_vc_vm_v2.baza.vault_secrets["имя_ключа"] -nubes_vc_vm_v2.baza.vault_url -nubes_vc_vm_v2.baza.vault_user_path -nubes_vc_vm_v2.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_vm_v2_ops.md b/generated/prod/docs/vc_vm_v2_ops.md deleted file mode 100644 index 9d940af..0000000 --- a/generated/prod/docs/vc_vm_v2_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vm_v2_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vm_v2_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/prod/docs/vc_vm_v2_outputs.md b/generated/prod/docs/vc_vm_v2_outputs.md deleted file mode 100644 index 3b9bace..0000000 --- a/generated/prod/docs/vc_vm_v2_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/vc_vm_v2_params.md b/generated/prod/docs/vc_vm_v2_params.md deleted file mode 100644 index e60c762..0000000 --- a/generated/prod/docs/vc_vm_v2_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Parameters - -- [Create params](vc_vm_v2_params_create.md) -- [Modify params](vc_vm_v2_params_modify.md) diff --git a/generated/prod/docs/vc_vm_v2_params_create.md b/generated/prod/docs/vc_vm_v2_params_create.md deleted file mode 100644 index b1c20cc..0000000 --- a/generated/prod/docs/vc_vm_v2_params_create.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - -None. - -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
301server_list_jsonjson[{}]Необходимо изменить vappUid и ipSpaceName
Пример конфигурации взять по ссылке ниже

Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2)
maxlength=65536; minlength=10
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/vc_vm_v2_params_modify.md b/generated/prod/docs/vc_vm_v2_params_modify.md deleted file mode 100644 index eedbec8..0000000 --- a/generated/prod/docs/vc_vm_v2_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
302server_list_jsonjsonОбъект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2)
maxlength=65536; minlength=10
diff --git a/generated/prod/docs/vc_vm_v3.md b/generated/prod/docs/vc_vm_v3.md deleted file mode 100644 index 95856d8..0000000 --- a/generated/prod/docs/vc_vm_v3.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## MAN - -
-# Документация по разворачиванию ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\ложь, определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed" (В нем не будет работать сбор метрик zabbix).

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики -
diff --git a/generated/prod/docs/vc_vm_v3_example.md b/generated/prod/docs/vc_vm_v3_example.md deleted file mode 100644 index af8e218..0000000 --- a/generated/prod/docs/vc_vm_v3_example.md +++ /dev/null @@ -1,53 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Copy-ready manifest (`vc_vm_v3_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vc_vm_v3" "baza" { - vapp_uid = "TODO" - ip_space_name = "TODO" - image_vm = "TODO" - user_public_key = "TODO" # Публичная часть SSH-Ключа для пользователя - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - vm_name = "web01" - vm_cpu = 1 # шт - vm_ram = 1 # Gb - user_login = "myuser" # Учётка SSH - access_port_list = ["22"] # По каким портам открыть доступ к ВМ. Порты 22, 10050 проставляются автоматически Пока доступно: 22 - SSH, 80 - HTTP, 443 - HTTPS, 10050 - ZABBIX -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vm_v3.baza.state_params["имя_ключа"] -nubes_vc_vm_v3.baza.state_out["имя_ключа"] -nubes_vc_vm_v3.baza.state_params_flat["имя_ключа"] -nubes_vc_vm_v3.baza.state_out_flat["имя_ключа"] -nubes_vc_vm_v3.baza.vault_secrets["имя_ключа"] -nubes_vc_vm_v3.baza.vault_url -nubes_vc_vm_v3.baza.vault_user_path -nubes_vc_vm_v3.baza.vault_fields -``` diff --git a/generated/prod/docs/vc_vm_v3_ops.md b/generated/prod/docs/vc_vm_v3_ops.md deleted file mode 100644 index 29b88fb..0000000 --- a/generated/prod/docs/vc_vm_v3_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vm_v3_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vm_v3_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/prod/docs/vc_vm_v3_outputs.md b/generated/prod/docs/vc_vm_v3_outputs.md deleted file mode 100644 index d0ef2e1..0000000 --- a/generated/prod/docs/vc_vm_v3_outputs.md +++ /dev/null @@ -1,30 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["fqdn"]` -- `state_out_flat["internalConnect"]` - diff --git a/generated/prod/docs/vc_vm_v3_params.md b/generated/prod/docs/vc_vm_v3_params.md deleted file mode 100644 index 9c63ad1..0000000 --- a/generated/prod/docs/vc_vm_v3_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Parameters - -- [Create params](vc_vm_v3_params_create.md) -- [Modify params](vc_vm_v3_params_modify.md) diff --git a/generated/prod/docs/vc_vm_v3_params_create.md b/generated/prod/docs/vc_vm_v3_params_create.md deleted file mode 100644 index aff77f9..0000000 --- a/generated/prod/docs/vc_vm_v3_params_create.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
407vapp_uiduuidref_svc_id=26
411vm_diskintegerОсновной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму
regex=^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$
412ip_space_namestring
413access_ip_listjsonФормат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено [&quot;0.0.0.0/0&quot;]
regex=^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$
414image_vmstring
415cloud_inityamlМожно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов.
417user_public_keystringПубличная часть SSH-Ключа для пользователя
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
408vm_namestringweb01regex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
409vm_cpuinteger1штminvalue=1; maxvalue=64
410vm_raminteger1Gbminvalue=1; maxvalue=256
416user_loginmyuserУчётка SSH
448access_port_liststring["22"]По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/prod/docs/vc_vm_v3_params_modify.md b/generated/prod/docs/vc_vm_v3_params_modify.md deleted file mode 100644 index 033040d..0000000 --- a/generated/prod/docs/vc_vm_v3_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
493vm_cpuintegerштminvalue=1; maxvalue=64
494vm_ramintegerGbminvalue=1; maxvalue=256
495vm_diskintegerОсновной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму
regex=^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$
496ip_space_namestringno-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev
value_list=no-needed, internet-antiddos-v1, internet-no-antiddos-v1
497access_ip_listjsonФормат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено [&quot;0.0.0.0/0&quot;]
498access_port_listjsonФормат массива
По каким портам открыть доступ к ВМ.
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS
diff --git a/generated/prod/docs/vcexternalip.md b/generated/prod/docs/vcexternalip.md deleted file mode 100644 index 3fe625c..0000000 --- a/generated/prod/docs/vcexternalip.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## MAN - -
-**Обычно эта услуга разворачивается автоматически при развёртывании более сложных услуг**
Вручную создавать можно, однако услуга требует много параметров, о которых можно просто не знать

Резервировать публичные IP адреса можно только после создания NGcloud Organization, NGcloud Виртуальный датацентр, NGcloud Каталог, Сетевой шлюз периметра.
Вы можете назначить IP адрес для существующего экземпляра сервиса. -
diff --git a/generated/prod/docs/vcexternalip_example.md b/generated/prod/docs/vcexternalip_example.md deleted file mode 100644 index 8d53544..0000000 --- a/generated/prod/docs/vcexternalip_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Copy-ready manifest (`vcexternalip_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vcexternalip" "baza" { - service_uid = "TODO" - internal_addr_access = "TODO" # Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true - from_service_namespace = "TODO" # Namespace составной услуги (для отображения правил FW) - ip_space_name = "TODO" # Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1) - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - dnat_create = true # Необходимо создать DNAT-правило. - internal_port_access = 5432 # Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vcexternalip.baza.state_params["имя_ключа"] -nubes_vcexternalip.baza.state_out["имя_ключа"] -nubes_vcexternalip.baza.state_params_flat["имя_ключа"] -nubes_vcexternalip.baza.state_out_flat["имя_ключа"] -nubes_vcexternalip.baza.vault_secrets["имя_ключа"] -nubes_vcexternalip.baza.vault_url -nubes_vcexternalip.baza.vault_user_path -nubes_vcexternalip.baza.vault_fields -``` diff --git a/generated/prod/docs/vcexternalip_ops.md b/generated/prod/docs/vcexternalip_ops.md deleted file mode 100644 index 5668481..0000000 --- a/generated/prod/docs/vcexternalip_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vcexternalip_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vcexternalip_params_modify.md) diff --git a/generated/prod/docs/vcexternalip_outputs.md b/generated/prod/docs/vcexternalip_outputs.md deleted file mode 100644 index aaa59e1..0000000 --- a/generated/prod/docs/vcexternalip_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalIp"]` - diff --git a/generated/prod/docs/vcexternalip_params.md b/generated/prod/docs/vcexternalip_params.md deleted file mode 100644 index 1db2fcc..0000000 --- a/generated/prod/docs/vcexternalip_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Parameters - -- [Create params](vcexternalip_params_create.md) -- [Modify params](vcexternalip_params_modify.md) diff --git a/generated/prod/docs/vcexternalip_params_create.md b/generated/prod/docs/vcexternalip_params_create.md deleted file mode 100644 index 995a3b8..0000000 --- a/generated/prod/docs/vcexternalip_params_create.md +++ /dev/null @@ -1,36 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
140service_uidstring
143snat_createbooleanНеобходимо создать SNAT-правило.
144internal_addr_accessstringВнутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true
324from_service_namespacestringNamespace составной услуги (для отображения правил FW)
325from_service_cloud_edge_namestringEdge составной услуги (указывать, если resourceRealm связан с CloudDirector)
326from_service_cloud_vdc_nameVdc составной услуги (указывать, если resourceRealm связан с CloudDirector)
327from_service_cloud_org_namestringOrg составной услуги (указывать, если resourceRealm связан с CloudDirector)
328from_service_cloud_vmware_urlstringApi-Url составной услуги (указывать, если resourceRealm связан с CloudDirector)
336ip_space_namestringТип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1)
488resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
624from_service_cloud_edge_scopestring
626from_service_vdc_group_namestring
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
141dnat_createbooleantrueНеобходимо создать DNAT-правило.
142internal_port_accessstring5432Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
diff --git a/generated/prod/docs/vcexternalip_params_modify.md b/generated/prod/docs/vcexternalip_params_modify.md deleted file mode 100644 index f17b66c..0000000 --- a/generated/prod/docs/vcexternalip_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
627service_uidstring
628ip_space_namestring
629dnat_createboolean
630snat_createboolean
631internal_port_accessstring
632internal_addr_accessstring
diff --git a/generated/prod/docs/vmpostgre.md b/generated/prod/docs/vmpostgre.md deleted file mode 100644 index 31d8dad..0000000 --- a/generated/prod/docs/vmpostgre.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## MAN - -
-Сервис настройки PostgreSQL для виртуальной машины.
Требует наличия ВМ -
diff --git a/generated/prod/docs/vmpostgre_example.md b/generated/prod/docs/vmpostgre_example.md deleted file mode 100644 index cebe6a2..0000000 --- a/generated/prod/docs/vmpostgre_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Copy-ready manifest (`vmpostgre_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "2.1.26" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://deck-api.ngcloud.ru/api/v1/index.cfm" -} -resource "nubes_vmpostgre" "baza" { - vdc_uid = "TODO" # InstanceUid vdc. Vdc должен быть создан - nsxt_uid = "TODO" # InstanceUid nsxt. Nsxt должен быть создан - vm_uid = "TODO" # InstanceUid ВМ. ВМ должна быть создана - resource_realm = "TODO" # Ресурсная платформа - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - user_db = "servicedb" # Наименование Базы данных - user_login = "serviceuser" # Пользователь базы данных - user_password = "fj29gm48fm!d374mc9" # Пароль от доступа к Базе данных -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vmpostgre.baza.state_params["имя_ключа"] -nubes_vmpostgre.baza.state_out["имя_ключа"] -nubes_vmpostgre.baza.state_params_flat["имя_ключа"] -nubes_vmpostgre.baza.state_out_flat["имя_ключа"] -nubes_vmpostgre.baza.vault_secrets["имя_ключа"] -nubes_vmpostgre.baza.vault_url -nubes_vmpostgre.baza.vault_user_path -nubes_vmpostgre.baza.vault_fields -``` diff --git a/generated/prod/docs/vmpostgre_ops.md b/generated/prod/docs/vmpostgre_ops.md deleted file mode 100644 index 306580c..0000000 --- a/generated/prod/docs/vmpostgre_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vmpostgre_params_create.md) -- `delete` diff --git a/generated/prod/docs/vmpostgre_outputs.md b/generated/prod/docs/vmpostgre_outputs.md deleted file mode 100644 index 5c8d505..0000000 --- a/generated/prod/docs/vmpostgre_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/prod/docs/vmpostgre_params.md b/generated/prod/docs/vmpostgre_params.md deleted file mode 100644 index 8b28da6..0000000 --- a/generated/prod/docs/vmpostgre_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Parameters - -- [Create params](vmpostgre_params_create.md) -- [Modify params](vmpostgre_params_modify.md) diff --git a/generated/prod/docs/vmpostgre_params_create.md b/generated/prod/docs/vmpostgre_params_create.md deleted file mode 100644 index 9d0a40e..0000000 --- a/generated/prod/docs/vmpostgre_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
43vdc_uiduuidInstanceUid vdc. Vdc должен быть создан
ref_svc_id=21
44nsxt_uiduuidInstanceUid nsxt. Nsxt должен быть создан
ref_svc_id=22
45vm_uiduuidInstanceUid ВМ. ВМ должна быть создана
ref_svc_id=23
859resource_realmstringРесурсная платформаfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
46user_dbstringservicedbНаименование Базы данных
47user_loginstringserviceuserПользователь базы данных
48user_passwordstringfj29gm48fm!d374mc9Пароль от доступа к Базе данных
diff --git a/generated/prod/docs/vmpostgre_params_modify.md b/generated/prod/docs/vmpostgre_params_modify.md deleted file mode 100644 index 9ce30ad..0000000 --- a/generated/prod/docs/vmpostgre_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Modify params - -None. diff --git a/generated/prod/go/.gitkeep b/generated/prod/go/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/prod/go/100_openwhisk_resource.go b/generated/prod/go/100_openwhisk_resource.go deleted file mode 100644 index a389f20..0000000 --- a/generated/prod/go/100_openwhisk_resource.go +++ /dev/null @@ -1,352 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: openwhisk -// Service ID: 100 - -var _ resource.Resource = &OpenwhiskResource{} -var _ resource.ResourceWithModifyPlan = &OpenwhiskResource{} -var _ resource.ResourceWithImportState = &OpenwhiskResource{} - -type OpenwhiskResource struct { - client *core.UniversalClient -} - -type OpenwhiskModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ResourceRealm types.String `tfsdk:"resource_realm"` - Username types.String `tfsdk:"username"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewOpenwhiskResource() resource.Resource { - return &OpenwhiskResource{} -} - -func (r *OpenwhiskResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_openwhisk" -} - -func (r *OpenwhiskResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Ресурсная платформа Не изменяется после создания."}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Имя пользователя Openwhisk Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *OpenwhiskResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *OpenwhiskModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *OpenwhiskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan OpenwhiskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Username.IsNull() && !plan.Username.IsUnknown() && !state.Username.IsNull() && !state.Username.IsUnknown() { - if plan.Username.ValueString() != state.Username.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить username", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.Username.IsNull() || config.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 64: resources_core.FormatString(config.Username), - 863: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 100, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *OpenwhiskResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data OpenwhiskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.Username.IsNull() || data.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 100, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 64: resources_core.FormatString(data.Username), - 863: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 100, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 100, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "username", Field: "Username", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *OpenwhiskResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state OpenwhiskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 100, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "username", Field: "Username", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *OpenwhiskResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan OpenwhiskModel - var state OpenwhiskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 100, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "username", Field: "Username", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *OpenwhiskResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state OpenwhiskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *OpenwhiskResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *OpenwhiskResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/110_dnszone_resource.go b/generated/prod/go/110_dnszone_resource.go deleted file mode 100644 index c0b9b1a..0000000 --- a/generated/prod/go/110_dnszone_resource.go +++ /dev/null @@ -1,452 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dnszone -// Service ID: 110 - -var _ resource.Resource = &DnszoneResource{} -var _ resource.ResourceWithModifyPlan = &DnszoneResource{} -var _ resource.ResourceWithImportState = &DnszoneResource{} - -type DnszoneResource struct { - client *core.UniversalClient -} - -type DnszoneModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ResourceRealm types.String `tfsdk:"resource_realm"` - ZoneEmail types.String `tfsdk:"zone_email"` - ZoneKind types.String `tfsdk:"zone_kind"` - ZoneMastersForSlave types.String `tfsdk:"zone_masters_for_slave"` - ZoneName types.String `tfsdk:"zone_name"` - ZoneTimeToExpire types.String `tfsdk:"zone_time_to_expire"` - ZoneTimeToLive types.String `tfsdk:"zone_time_to_live"` - ZoneTimeToRefresh types.String `tfsdk:"zone_time_to_refresh"` - ZoneTimeToRetry types.String `tfsdk:"zone_time_to_retry"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDnszoneResource() resource.Resource { - return &DnszoneResource{} -} - -func (r *DnszoneResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dnszone" -} - -func (r *DnszoneResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "zone_email": schema.StringAttribute{Required: true, MarkdownDescription: "Контактный e-mail Не изменяется после создания."}, - "zone_kind": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("NATIVE"), MarkdownDescription: "Тип зоны Не изменяется после создания."}, - "zone_masters_for_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Использовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов Не изменяется после создания."}, - "zone_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя зоны Не изменяется после создания."}, - "zone_time_to_expire": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("3600000"), MarkdownDescription: "Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным Не изменяется после создания."}, - "zone_time_to_live": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("86400"), MarkdownDescription: "Время, в течение которого информация будет кешироваться другими DNS-серверами Не изменяется после создания."}, - "zone_time_to_refresh": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("86400"), MarkdownDescription: "Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов Не изменяется после создания."}, - "zone_time_to_retry": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("7200"), MarkdownDescription: "Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DnszoneResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DnszoneModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneEmail.IsNull() && !plan.ZoneEmail.IsUnknown() && !state.ZoneEmail.IsNull() && !state.ZoneEmail.IsUnknown() { - if plan.ZoneEmail.ValueString() != state.ZoneEmail.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_email", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneKind.IsNull() && !plan.ZoneKind.IsUnknown() && !state.ZoneKind.IsNull() && !state.ZoneKind.IsUnknown() { - if plan.ZoneKind.ValueString() != state.ZoneKind.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_kind", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneMastersForSlave.IsNull() && !plan.ZoneMastersForSlave.IsUnknown() && !state.ZoneMastersForSlave.IsNull() && !state.ZoneMastersForSlave.IsUnknown() { - if plan.ZoneMastersForSlave.ValueString() != state.ZoneMastersForSlave.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_masters_for_slave", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneName.IsNull() && !plan.ZoneName.IsUnknown() && !state.ZoneName.IsNull() && !state.ZoneName.IsUnknown() { - if plan.ZoneName.ValueString() != state.ZoneName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToExpire.IsNull() && !plan.ZoneTimeToExpire.IsUnknown() && !state.ZoneTimeToExpire.IsNull() && !state.ZoneTimeToExpire.IsUnknown() { - if plan.ZoneTimeToExpire.ValueString() != state.ZoneTimeToExpire.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_expire", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToLive.IsNull() && !plan.ZoneTimeToLive.IsUnknown() && !state.ZoneTimeToLive.IsNull() && !state.ZoneTimeToLive.IsUnknown() { - if plan.ZoneTimeToLive.ValueString() != state.ZoneTimeToLive.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_live", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToRefresh.IsNull() && !plan.ZoneTimeToRefresh.IsUnknown() && !state.ZoneTimeToRefresh.IsNull() && !state.ZoneTimeToRefresh.IsUnknown() { - if plan.ZoneTimeToRefresh.ValueString() != state.ZoneTimeToRefresh.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_refresh", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToRetry.IsNull() && !plan.ZoneTimeToRetry.IsUnknown() && !state.ZoneTimeToRetry.IsNull() && !state.ZoneTimeToRetry.IsUnknown() { - if plan.ZoneTimeToRetry.ValueString() != state.ZoneTimeToRetry.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_retry", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ZoneEmail.IsNull() || config.ZoneEmail.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_email is required.") - return - } - if config.ZoneName.IsNull() || config.ZoneName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_name is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 66: resources_core.FormatString(config.ZoneEmail), - 67: resources_core.FormatString(config.ZoneName), - 68: resources_core.FormatString(config.ZoneKind), - 69: resources_core.FormatString(config.ZoneMastersForSlave), - 70: resources_core.FormatString(config.ZoneTimeToRefresh), - 71: resources_core.FormatString(config.ZoneTimeToRetry), - 72: resources_core.FormatString(config.ZoneTimeToExpire), - 73: resources_core.FormatString(config.ZoneTimeToLive), - 284: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 110, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DnszoneResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.ZoneEmail.IsNull() || data.ZoneEmail.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_email is required.") - return - } - if data.ZoneName.IsNull() || data.ZoneName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_name is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 110, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 66: resources_core.FormatString(data.ZoneEmail), - 67: resources_core.FormatString(data.ZoneName), - 68: resources_core.FormatString(data.ZoneKind), - 69: resources_core.FormatString(data.ZoneMastersForSlave), - 70: resources_core.FormatString(data.ZoneTimeToRefresh), - 71: resources_core.FormatString(data.ZoneTimeToRetry), - 72: resources_core.FormatString(data.ZoneTimeToExpire), - 73: resources_core.FormatString(data.ZoneTimeToLive), - 284: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 110, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 110, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnszoneResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 110, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DnszoneResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DnszoneModel - var state DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 110, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnszoneResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DnszoneResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DnszoneResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/111_dnsrecord_resource.go b/generated/prod/go/111_dnsrecord_resource.go deleted file mode 100644 index c52b61d..0000000 --- a/generated/prod/go/111_dnsrecord_resource.go +++ /dev/null @@ -1,471 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dnsrecord -// Service ID: 111 - -var _ resource.Resource = &DnsrecordResource{} -var _ resource.ResourceWithModifyPlan = &DnsrecordResource{} -var _ resource.ResourceWithImportState = &DnsrecordResource{} - -type DnsrecordResource struct { - client *core.UniversalClient -} - -type DnsrecordModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - RecordInput types.String `tfsdk:"record_input"` - RecordName types.String `tfsdk:"record_name"` - RecordTTL types.Int64 `tfsdk:"record_t_t_l"` - RecordType types.String `tfsdk:"record_type"` - ZoneUid types.String `tfsdk:"zone_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDnsrecordResource() resource.Resource { - return &DnsrecordResource{} -} - -func (r *DnsrecordResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dnsrecord" -} - -func (r *DnsrecordResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "record_input": schema.StringAttribute{Required: true, MarkdownDescription: "Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP"}, - "record_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя записи. Имя зоны в конце проставляется автоматически Не изменяется после создания."}, - "record_t_t_l": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(3600), MarkdownDescription: "Time-to-Leave записи. Раз в какое время запись будет обновлена Не изменяется после создания."}, - "record_type": schema.StringAttribute{Required: true, MarkdownDescription: "Тип DNS-записи Не изменяется после создания."}, - "zone_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID экземпляра услуги DNS-зоны Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DnsrecordResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DnsrecordModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.ZoneUid.IsNull() && !plan.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, plan.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != plan.ZoneUid.ValueString() { - plan.ZoneUid = types.StringValue(resolvedZoneUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.RecordName.IsNull() && !plan.RecordName.IsUnknown() && !state.RecordName.IsNull() && !state.RecordName.IsUnknown() { - if plan.RecordName.ValueString() != state.RecordName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить record_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RecordTTL.IsNull() && !plan.RecordTTL.IsUnknown() && !state.RecordTTL.IsNull() && !state.RecordTTL.IsUnknown() { - if plan.RecordTTL.ValueInt64() != state.RecordTTL.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить record_t_t_l", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RecordType.IsNull() && !plan.RecordType.IsUnknown() && !state.RecordType.IsNull() && !state.RecordType.IsUnknown() { - if plan.RecordType.ValueString() != state.RecordType.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить record_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneUid.IsNull() && !plan.ZoneUid.IsUnknown() && !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - if plan.ZoneUid.ValueString() != state.ZoneUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить zone_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.RecordInput.IsNull() || config.RecordInput.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_input is required.") - return - } - if config.RecordName.IsNull() || config.RecordName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_name is required.") - return - } - if config.RecordType.IsNull() || config.RecordType.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_type is required.") - return - } - if config.ZoneUid.IsNull() || config.ZoneUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.ZoneUid.IsNull() && !config.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, config.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != config.ZoneUid.ValueString() { - config.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - params := map[int]string{ - 75: resources_core.FormatString(config.ZoneUid), - 76: resources_core.FormatString(config.RecordType), - 77: resources_core.FormatString(config.RecordName), - 78: resources_core.FormatString(config.RecordInput), - 450: resources_core.FormatInt64(config.RecordTTL), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 111, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DnsrecordResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.RecordInput.IsNull() || data.RecordInput.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_input is required.") - return - } - if data.RecordName.IsNull() || data.RecordName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_name is required.") - return - } - if data.RecordType.IsNull() || data.RecordType.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_type is required.") - return - } - if data.ZoneUid.IsNull() || data.ZoneUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_uid is required.") - return - } - if !data.ZoneUid.IsNull() && !data.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, data.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedZoneUid != "" && resolvedZoneUid != data.ZoneUid.ValueString() { - data.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 111, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 75: resources_core.FormatString(data.ZoneUid), - 76: resources_core.FormatString(data.RecordType), - 77: resources_core.FormatString(data.RecordName), - 78: resources_core.FormatString(data.RecordInput), - 450: resources_core.FormatInt64(data.RecordTTL), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 111, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 111, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, state.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != state.ZoneUid.ValueString() { - state.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnsrecordResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 111, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.ZoneUid.IsNull() && !newState.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, newState.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != newState.ZoneUid.ValueString() { - newState.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DnsrecordResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DnsrecordModel - var state DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.RecordInput.IsNull() != state.RecordInput.IsNull() || plan.RecordInput.IsUnknown() != state.RecordInput.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.RecordInput.IsNull() && !plan.RecordInput.IsUnknown() && !state.RecordInput.IsNull() && !state.RecordInput.IsUnknown() { - if plan.RecordInput.ValueString() != state.RecordInput.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 256: resources_core.FormatString(plan.RecordInput), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 111, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 110, state.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != state.ZoneUid.ValueString() { - state.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnsrecordResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DnsrecordResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DnsrecordResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/112_tenant_resource.go b/generated/prod/go/112_tenant_resource.go deleted file mode 100644 index bea2f79..0000000 --- a/generated/prod/go/112_tenant_resource.go +++ /dev/null @@ -1,352 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: tenant -// Service ID: 112 - -var _ resource.Resource = &TenantResource{} -var _ resource.ResourceWithModifyPlan = &TenantResource{} -var _ resource.ResourceWithImportState = &TenantResource{} - -type TenantResource struct { - client *core.UniversalClient -} - -type TenantModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - GrafanaOrgName types.String `tfsdk:"grafana_org_name"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewTenantResource() resource.Resource { - return &TenantResource{} -} - -func (r *TenantResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_tenant" -} - -func (r *TenantResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "grafana_org_name": schema.StringAttribute{Required: true, MarkdownDescription: "WZ-Код клиента Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *TenantResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *TenantModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *TenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan TenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.GrafanaOrgName.IsNull() && !plan.GrafanaOrgName.IsUnknown() && !state.GrafanaOrgName.IsNull() && !state.GrafanaOrgName.IsUnknown() { - if plan.GrafanaOrgName.ValueString() != state.GrafanaOrgName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить grafana_org_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.GrafanaOrgName.IsNull() || config.GrafanaOrgName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "grafana_org_name is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 239: resources_core.FormatString(config.GrafanaOrgName), - 240: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 112, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *TenantResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data TenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.GrafanaOrgName.IsNull() || data.GrafanaOrgName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "grafana_org_name is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 112, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 239: resources_core.FormatString(data.GrafanaOrgName), - 240: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 112, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 112, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "grafanaOrgName", Field: "GrafanaOrgName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TenantResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state TenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 112, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "grafanaOrgName", Field: "GrafanaOrgName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *TenantResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan TenantModel - var state TenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 112, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "grafanaOrgName", Field: "GrafanaOrgName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TenantResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state TenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *TenantResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *TenantResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/113_vc_complex_resource.go b/generated/prod/go/113_vc_complex_resource.go deleted file mode 100644 index b3e5bd1..0000000 --- a/generated/prod/go/113_vc_complex_resource.go +++ /dev/null @@ -1,523 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_complex -// Service ID: 113 - -var _ resource.Resource = &VcComplexResource{} -var _ resource.ResourceWithModifyPlan = &VcComplexResource{} -var _ resource.ResourceWithImportState = &VcComplexResource{} - -type VcComplexResource struct { - client *core.UniversalClient -} - -type VcComplexModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - CpuAllocated types.String `tfsdk:"cpu_allocated"` - CpuGuaranteed types.Int64 `tfsdk:"cpu_guaranteed"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - MemAllocated types.Int64 `tfsdk:"mem_allocated"` - MemGuaranteed types.Int64 `tfsdk:"mem_guaranteed"` - NeedEnableAVI types.Bool `tfsdk:"need_enable_a_v_i"` - NeedExternalAddressSNAT types.Bool `tfsdk:"need_external_address_s_n_a_t"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SegroupName types.String `tfsdk:"segroup_name"` - StorageConfig types.String `tfsdk:"storage_config"` - VIPCount types.Int64 `tfsdk:"v_i_p_count"` - VappName types.String `tfsdk:"vapp_name"` - VdcNetworkPool types.String `tfsdk:"vdc_network_pool"` - VdcProviderGateway types.String `tfsdk:"vdc_provider_gateway"` - VirtualServicesCount types.String `tfsdk:"virtual_services_count"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcComplexResource() resource.Resource { - return &VcComplexResource{} -} - -func (r *VcComplexResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_complex" -} - -func (r *VcComplexResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "cpu_allocated": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("1"), MarkdownDescription: "шт Не изменяется после создания."}, - "cpu_guaranteed": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "Не изменяется после создания."}, - "ip_space_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("internet-ipv4-v1"), MarkdownDescription: "Имя ip Space для внешнего IP. Целесообразнее брать самый дешёвый, так как это vip для исходящего трафика. Необходимо задавать если включен needExternalAddressSNAT Не изменяется после создания."}, - "mem_allocated": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "gb Не изменяется после создания."}, - "mem_guaranteed": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "Не изменяется после создания."}, - "need_enable_a_v_i": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает AVI в Cloud Director Не изменяется после создания."}, - "need_external_address_s_n_a_t": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Выделяет внешний IP на Edge. Используется для SNAT всего трафика Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "segroup_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("SEGROUP-SANDBOX-CL1-SHARED-01"), MarkdownDescription: "Наименование segroup, в котором будут выделяться пулы на AVI Не изменяется после создания."}, - "storage_config": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{\"name\": \"\", \"size\": 1024}]"), MarkdownDescription: "Описывается как массив объектов, где описывается имя политики и её размер Не изменяется после создания."}, - "v_i_p_count": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "ш Не изменяется после создания."}, - "vapp_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя vApp Не изменяется после создания."}, - "vdc_network_pool": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("nsxt-sandbox-geneve-np"), MarkdownDescription: "Не изменяется после создания."}, - "vdc_provider_gateway": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("sandbox-v1cl1-pvdc"), MarkdownDescription: "Взять из свойств ресурсной платформы.
Путь .vcd.providerVdc - взять KEY

providerGateway Cloud Director. Влияет ресурсы будут предоставлены. Является полем (List<String>) в свойствах рес. платформы ЛК, но сам параметр передаётся только как один String Не изменяется после создания."}, - "virtual_services_count": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("1"), MarkdownDescription: "Кол-во виртуальных сервисов, которые выделяются на AVI. Во избежании коллапса пока выделяется до 4 Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcComplexResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcComplexModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.CpuAllocated.IsNull() && !plan.CpuAllocated.IsUnknown() && !state.CpuAllocated.IsNull() && !state.CpuAllocated.IsUnknown() { - if plan.CpuAllocated.ValueString() != state.CpuAllocated.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить cpu_allocated", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.CpuGuaranteed.IsNull() && !plan.CpuGuaranteed.IsUnknown() && !state.CpuGuaranteed.IsNull() && !state.CpuGuaranteed.IsUnknown() { - if plan.CpuGuaranteed.ValueInt64() != state.CpuGuaranteed.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить cpu_guaranteed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MemAllocated.IsNull() && !plan.MemAllocated.IsUnknown() && !state.MemAllocated.IsNull() && !state.MemAllocated.IsUnknown() { - if plan.MemAllocated.ValueInt64() != state.MemAllocated.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить mem_allocated", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MemGuaranteed.IsNull() && !plan.MemGuaranteed.IsUnknown() && !state.MemGuaranteed.IsNull() && !state.MemGuaranteed.IsUnknown() { - if plan.MemGuaranteed.ValueInt64() != state.MemGuaranteed.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить mem_guaranteed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedEnableAVI.IsNull() && !plan.NeedEnableAVI.IsUnknown() && !state.NeedEnableAVI.IsNull() && !state.NeedEnableAVI.IsUnknown() { - if plan.NeedEnableAVI.ValueBool() != state.NeedEnableAVI.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_enable_a_v_i", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressSNAT.IsNull() && !plan.NeedExternalAddressSNAT.IsUnknown() && !state.NeedExternalAddressSNAT.IsNull() && !state.NeedExternalAddressSNAT.IsUnknown() { - if plan.NeedExternalAddressSNAT.ValueBool() != state.NeedExternalAddressSNAT.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_s_n_a_t", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.SegroupName.IsNull() && !plan.SegroupName.IsUnknown() && !state.SegroupName.IsNull() && !state.SegroupName.IsUnknown() { - if plan.SegroupName.ValueString() != state.SegroupName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить segroup_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.StorageConfig.IsNull() && !plan.StorageConfig.IsUnknown() && !state.StorageConfig.IsNull() && !state.StorageConfig.IsUnknown() { - if plan.StorageConfig.ValueString() != state.StorageConfig.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить storage_config", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VIPCount.IsNull() && !plan.VIPCount.IsUnknown() && !state.VIPCount.IsNull() && !state.VIPCount.IsUnknown() { - if plan.VIPCount.ValueInt64() != state.VIPCount.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить v_i_p_count", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappName.IsNull() && !plan.VappName.IsUnknown() && !state.VappName.IsNull() && !state.VappName.IsUnknown() { - if plan.VappName.ValueString() != state.VappName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vapp_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcNetworkPool.IsNull() && !plan.VdcNetworkPool.IsUnknown() && !state.VdcNetworkPool.IsNull() && !state.VdcNetworkPool.IsUnknown() { - if plan.VdcNetworkPool.ValueString() != state.VdcNetworkPool.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_network_pool", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcProviderGateway.IsNull() && !plan.VdcProviderGateway.IsUnknown() && !state.VdcProviderGateway.IsNull() && !state.VdcProviderGateway.IsUnknown() { - if plan.VdcProviderGateway.ValueString() != state.VdcProviderGateway.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_provider_gateway", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VirtualServicesCount.IsNull() && !plan.VirtualServicesCount.IsUnknown() && !state.VirtualServicesCount.IsNull() && !state.VirtualServicesCount.IsUnknown() { - if plan.VirtualServicesCount.ValueString() != state.VirtualServicesCount.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить virtual_services_count", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.VappName.IsNull() || config.VappName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 332: resources_core.FormatString(config.ResourceRealm), - 334: resources_core.FormatString(config.VappName), - 358: resources_core.FormatString(config.VdcProviderGateway), - 359: resources_core.FormatString(config.VirtualServicesCount), - 360: resources_core.FormatString(config.IpSpaceName), - 399: resources_core.FormatString(config.StorageConfig), - 400: resources_core.FormatString(config.VdcNetworkPool), - 401: resources_core.FormatInt64(config.CpuGuaranteed), - 402: resources_core.FormatInt64(config.MemGuaranteed), - 403: resources_core.FormatString(config.SegroupName), - 404: resources_core.FormatBool(config.NeedExternalAddressSNAT), - 405: resources_core.FormatBool(config.NeedEnableAVI), - 566: resources_core.FormatString(config.CpuAllocated), - 567: resources_core.FormatInt64(config.MemAllocated), - 568: resources_core.FormatInt64(config.VIPCount), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 113, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcComplexResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.VappName.IsNull() || data.VappName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 113, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 332: resources_core.FormatString(data.ResourceRealm), - 334: resources_core.FormatString(data.VappName), - 358: resources_core.FormatString(data.VdcProviderGateway), - 359: resources_core.FormatString(data.VirtualServicesCount), - 360: resources_core.FormatString(data.IpSpaceName), - 399: resources_core.FormatString(data.StorageConfig), - 400: resources_core.FormatString(data.VdcNetworkPool), - 401: resources_core.FormatInt64(data.CpuGuaranteed), - 402: resources_core.FormatInt64(data.MemGuaranteed), - 403: resources_core.FormatString(data.SegroupName), - 404: resources_core.FormatBool(data.NeedExternalAddressSNAT), - 405: resources_core.FormatBool(data.NeedEnableAVI), - 566: resources_core.FormatString(data.CpuAllocated), - 567: resources_core.FormatInt64(data.MemAllocated), - 568: resources_core.FormatInt64(data.VIPCount), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 113, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 113, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "string"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "segroupName", Field: "SegroupName", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - {Code: "vIPCount", Field: "VIPCount", Type: "int64"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcNetworkPool", Field: "VdcNetworkPool", Type: "string"}, - {Code: "vdcProviderGateway", Field: "VdcProviderGateway", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcComplexResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 113, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "string"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "segroupName", Field: "SegroupName", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - {Code: "vIPCount", Field: "VIPCount", Type: "int64"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcNetworkPool", Field: "VdcNetworkPool", Type: "string"}, - {Code: "vdcProviderGateway", Field: "VdcProviderGateway", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcComplexResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcComplexModel - var state VcComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 113, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "string"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "segroupName", Field: "SegroupName", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - {Code: "vIPCount", Field: "VIPCount", Type: "int64"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcNetworkPool", Field: "VdcNetworkPool", Type: "string"}, - {Code: "vdcProviderGateway", Field: "VdcProviderGateway", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcComplexResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcComplexResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcComplexResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/114_gitea_complex_resource.go b/generated/prod/go/114_gitea_complex_resource.go deleted file mode 100644 index a1320ad..0000000 --- a/generated/prod/go/114_gitea_complex_resource.go +++ /dev/null @@ -1,305 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: gitea_complex -// Service ID: 114 - -var _ resource.Resource = &GiteaComplexResource{} -var _ resource.ResourceWithModifyPlan = &GiteaComplexResource{} -var _ resource.ResourceWithImportState = &GiteaComplexResource{} - -type GiteaComplexResource struct { - client *core.UniversalClient -} - -type GiteaComplexModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewGiteaComplexResource() resource.Resource { - return &GiteaComplexResource{} -} - -func (r *GiteaComplexResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_gitea_complex" -} - -func (r *GiteaComplexResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *GiteaComplexResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *GiteaComplexModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *GiteaComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan GiteaComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{} - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 114, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *GiteaComplexResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data GiteaComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 114, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{} - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 114, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 114, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaComplexResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state GiteaComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 114, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *GiteaComplexResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan GiteaComplexModel - var state GiteaComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 114, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaComplexResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state GiteaComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *GiteaComplexResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *GiteaComplexResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/115_mariadb_resource.go b/generated/prod/go/115_mariadb_resource.go deleted file mode 100644 index 11f1547..0000000 --- a/generated/prod/go/115_mariadb_resource.go +++ /dev/null @@ -1,579 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mariadb -// Service ID: 115 - -var _ resource.Resource = &MariadbResource{} -var _ resource.ResourceWithModifyPlan = &MariadbResource{} -var _ resource.ResourceWithImportState = &MariadbResource{} - -type MariadbResource struct { - client *core.UniversalClient -} - -type MariadbModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AppVersion types.String `tfsdk:"app_version"` - AutoScale types.Bool `tfsdk:"auto_scale"` - AutoScalePercentage types.Int64 `tfsdk:"auto_scale_percentage"` - AutoScaleQuotaGb types.Int64 `tfsdk:"auto_scale_quota_gb"` - AutoScaleTechWindow types.Int64 `tfsdk:"auto_scale_tech_window"` - ExtBACKUPSCHEDULE types.String `tfsdk:"ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewMariadbResource() resource.Resource { - return &MariadbResource{} -} - -func (r *MariadbResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mariadb" -} - -func (r *MariadbResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("9.4.0"), MarkdownDescription: "Версия MySQL Не изменяется после создания."}, - "auto_scale": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги"}, - "auto_scale_percentage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема"}, - "auto_scale_quota_gb": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота для autoScale"}, - "auto_scale_tech_window": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23)"}, - "ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("0 * * * *"), MarkdownDescription: "Не обязательный. Время запуска бекапа"}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к master"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores)"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MariadbResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *MariadbModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() { - plan.S3Uid = types.StringValue(resolvedS3Uid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить app_version", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - if plan.S3Uid.ValueString() != state.S3Uid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 422: resources_core.FormatString(config.ResourceRealm), - 424: resources_core.FormatInt64(config.ResourceCPU), - 425: resources_core.FormatInt64(config.ResourceMemory), - 426: resources_core.FormatInt64(config.ResourceDisk), - 427: resources_core.FormatInt64(config.ResourceInstances), - 428: resources_core.FormatBool(config.NeedExternalAddressMaster), - 429: resources_core.FormatString(config.IpSpaceNameMaster), - 430: resources_core.FormatString(config.ExtBACKUPSCHEDULE), - 431: resources_core.FormatString(config.AppVersion), - 432: resources_core.FormatBool(config.AutoScale), - 433: resources_core.FormatInt64(config.AutoScalePercentage), - 434: resources_core.FormatInt64(config.AutoScaleTechWindow), - 435: resources_core.FormatInt64(config.AutoScaleQuotaGb), - 459: resources_core.FormatString(config.S3Uid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 115, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *MariadbResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 115, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 422: resources_core.FormatString(data.ResourceRealm), - 424: resources_core.FormatInt64(data.ResourceCPU), - 425: resources_core.FormatInt64(data.ResourceMemory), - 426: resources_core.FormatInt64(data.ResourceDisk), - 427: resources_core.FormatInt64(data.ResourceInstances), - 428: resources_core.FormatBool(data.NeedExternalAddressMaster), - 429: resources_core.FormatString(data.IpSpaceNameMaster), - 430: resources_core.FormatString(data.ExtBACKUPSCHEDULE), - 431: resources_core.FormatString(data.AppVersion), - 432: resources_core.FormatBool(data.AutoScale), - 433: resources_core.FormatInt64(data.AutoScalePercentage), - 434: resources_core.FormatInt64(data.AutoScaleTechWindow), - 435: resources_core.FormatInt64(data.AutoScaleQuotaGb), - 459: resources_core.FormatString(data.S3Uid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 115, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 115, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "int64"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 115, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "int64"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *MariadbResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MariadbModel - var state MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPSCHEDULE.IsNull() != state.ExtBACKUPSCHEDULE.IsNull() || plan.ExtBACKUPSCHEDULE.IsUnknown() != state.ExtBACKUPSCHEDULE.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPSCHEDULE.IsNull() && !plan.ExtBACKUPSCHEDULE.IsUnknown() && !state.ExtBACKUPSCHEDULE.IsNull() && !state.ExtBACKUPSCHEDULE.IsUnknown() { - if plan.ExtBACKUPSCHEDULE.ValueString() != state.ExtBACKUPSCHEDULE.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoScale.IsNull() != state.AutoScale.IsNull() || plan.AutoScale.IsUnknown() != state.AutoScale.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoScale.IsNull() && !plan.AutoScale.IsUnknown() && !state.AutoScale.IsNull() && !state.AutoScale.IsUnknown() { - if plan.AutoScale.ValueBool() != state.AutoScale.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoScalePercentage.IsNull() != state.AutoScalePercentage.IsNull() || plan.AutoScalePercentage.IsUnknown() != state.AutoScalePercentage.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoScalePercentage.IsNull() && !plan.AutoScalePercentage.IsUnknown() && !state.AutoScalePercentage.IsNull() && !state.AutoScalePercentage.IsUnknown() { - if plan.AutoScalePercentage.ValueInt64() != state.AutoScalePercentage.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoScaleTechWindow.IsNull() != state.AutoScaleTechWindow.IsNull() || plan.AutoScaleTechWindow.IsUnknown() != state.AutoScaleTechWindow.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoScaleTechWindow.IsNull() && !plan.AutoScaleTechWindow.IsUnknown() && !state.AutoScaleTechWindow.IsNull() && !state.AutoScaleTechWindow.IsUnknown() { - if plan.AutoScaleTechWindow.ValueInt64() != state.AutoScaleTechWindow.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoScaleQuotaGb.IsNull() != state.AutoScaleQuotaGb.IsNull() || plan.AutoScaleQuotaGb.IsUnknown() != state.AutoScaleQuotaGb.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoScaleQuotaGb.IsNull() && !plan.AutoScaleQuotaGb.IsUnknown() && !state.AutoScaleQuotaGb.IsNull() && !state.AutoScaleQuotaGb.IsUnknown() { - if plan.AutoScaleQuotaGb.ValueInt64() != state.AutoScaleQuotaGb.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 436: resources_core.FormatInt64(plan.ResourceCPU), - 437: resources_core.FormatInt64(plan.ResourceMemory), - 438: resources_core.FormatInt64(plan.ResourceInstances), - 439: resources_core.FormatInt64(plan.ResourceDisk), - 440: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 441: resources_core.FormatString(plan.IpSpaceNameMaster), - 442: resources_core.FormatString(plan.ExtBACKUPSCHEDULE), - 443: resources_core.FormatBool(plan.AutoScale), - 444: resources_core.FormatInt64(plan.AutoScalePercentage), - 445: resources_core.FormatInt64(plan.AutoScaleTechWindow), - 446: resources_core.FormatInt64(plan.AutoScaleQuotaGb), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 115, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "int64"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *MariadbResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *MariadbResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/116_kafka_resource.go b/generated/prod/go/116_kafka_resource.go deleted file mode 100644 index 0bb9982..0000000 --- a/generated/prod/go/116_kafka_resource.go +++ /dev/null @@ -1,469 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Service ID: 116 - -var _ resource.Resource = &KafkaResource{} -var _ resource.ResourceWithModifyPlan = &KafkaResource{} -var _ resource.ResourceWithImportState = &KafkaResource{} - -type KafkaResource struct { - client *core.UniversalClient -} - -type KafkaModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewKafkaResource() resource.Resource { - return &KafkaResource{} -} - -func (r *KafkaResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka" -} - -func (r *KafkaResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`"}, - "resource_c_p_u": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2000`"}, - "resource_disk": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `20`"}, - "resource_instances": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2`"}, - "resource_memory": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *KafkaModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceCPU.IsNull() || config.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if config.ResourceDisk.IsNull() || config.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if config.ResourceInstances.IsNull() || config.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if config.ResourceMemory.IsNull() || config.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 461: resources_core.FormatInt64(config.ResourceInstances), - 462: resources_core.FormatInt64(config.ResourceMemory), - 463: resources_core.FormatInt64(config.ResourceCPU), - 464: resources_core.FormatInt64(config.ResourceDisk), - 465: resources_core.FormatBool(config.NeedExternalAddressMaster), - 466: resources_core.FormatString(config.IpSpaceNameMaster), - 469: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 116, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *KafkaResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceCPU.IsNull() || data.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if data.ResourceDisk.IsNull() || data.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if data.ResourceInstances.IsNull() || data.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if data.ResourceMemory.IsNull() || data.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 116, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 461: resources_core.FormatInt64(data.ResourceInstances), - 462: resources_core.FormatInt64(data.ResourceMemory), - 463: resources_core.FormatInt64(data.ResourceCPU), - 464: resources_core.FormatInt64(data.ResourceDisk), - 465: resources_core.FormatBool(data.NeedExternalAddressMaster), - 466: resources_core.FormatString(data.IpSpaceNameMaster), - 469: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 116, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 116, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 116, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *KafkaResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaModel - var state KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 501: resources_core.FormatInt64(plan.ResourceInstances), - 502: resources_core.FormatInt64(plan.ResourceMemory), - 503: resources_core.FormatInt64(plan.ResourceCPU), - 504: resources_core.FormatInt64(plan.ResourceDisk), - 505: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 506: resources_core.FormatString(plan.IpSpaceNameMaster), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 116, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *KafkaResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *KafkaResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/116_kafka_topic_resource.go b/generated/prod/go/116_kafka_topic_resource.go deleted file mode 100644 index 1694f27..0000000 --- a/generated/prod/go/116_kafka_topic_resource.go +++ /dev/null @@ -1,357 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Subresource: topic - -var _ resource.Resource = &KafkaTopicResource{} - -// KafkaTopicResource manages a subresource via operations. -type KafkaTopicResource struct { - client *core.UniversalClient -} - -type KafkaTopicModel struct { - ID types.String `tfsdk:"id"` - KafkaID types.String `tfsdk:"kafka_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - NameTopic types.String `tfsdk:"name_topic"` - Partitions types.Int64 `tfsdk:"partitions"` - Replicas types.Int64 `tfsdk:"replicas"` -} - -func NewKafkaTopicResource() resource.Resource { - return &KafkaTopicResource{} -} - -func (r *KafkaTopicResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka_topic" -} - -func (r *KafkaTopicResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "kafka_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events` Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "partitions": schema.Int64Attribute{Required: true, MarkdownDescription: "Число партиций можно увеличить, но уменьшить их нельзя."}, - "replicas": schema.Int64Attribute{Required: true, MarkdownDescription: "Количество реплик не может привышать количество реплик брокера"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaTopicResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan KafkaTopicModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.NameTopic.IsNull() || plan.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if plan.Partitions.IsNull() || plan.Partitions.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "partitions is required.") - return - } - if plan.Replicas.IsNull() || plan.Replicas.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "replicas is required.") - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - } - identityCodes := []string{ - "nameTopic", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("topic", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "partitions": resources_core.FormatInt64(plan.Partitions), - "replicas": resources_core.FormatInt64(plan.Replicas), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_topic", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_topic", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaTopicResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaTopicResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaTopicModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_topic" == "" { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "partitions": resources_core.FormatInt64(plan.Partitions), - "replicas": resources_core.FormatInt64(plan.Replicas), - }) - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_topic", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaTopicResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_topic" == "" { - return - } - - instanceUID := strings.TrimSpace(state.KafkaID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(state.NameTopic), - } - identityCodes := []string{ - "nameTopic", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("topic", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(state.NameTopic), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_topic", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *KafkaTopicResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/116_kafka_user_resource.go b/generated/prod/go/116_kafka_user_resource.go deleted file mode 100644 index bc12dd9..0000000 --- a/generated/prod/go/116_kafka_user_resource.go +++ /dev/null @@ -1,373 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Subresource: user - -var _ resource.Resource = &KafkaUserResource{} - -// KafkaUserResource manages a subresource via operations. -type KafkaUserResource struct { - client *core.UniversalClient -} - -type KafkaUserModel struct { - ID types.String `tfsdk:"id"` - KafkaID types.String `tfsdk:"kafka_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AccessHosts types.String `tfsdk:"access_hosts"` - Group types.String `tfsdk:"group"` - NameTopic types.String `tfsdk:"name_topic"` - Operations types.String `tfsdk:"operations"` - Username types.String `tfsdk:"username"` -} - -func NewKafkaUserResource() resource.Resource { - return &KafkaUserResource{} -} - -func (r *KafkaUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka_user" -} - -func (r *KafkaUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "kafka_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "access_hosts": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `192.168.1.0/24` или `*`"}, - "group": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `order-consumers` или `*`"}, - "name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`"}, - "operations": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `Create, Describe, Read, Write`"}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `username-admin` Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan KafkaUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.AccessHosts.IsNull() || plan.AccessHosts.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_hosts is required.") - return - } - if plan.Group.IsNull() || plan.Group.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "group is required.") - return - } - if plan.NameTopic.IsNull() || plan.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if plan.Operations.IsNull() || plan.Operations.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "operations is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "nameTopic": resources_core.FormatString(plan.NameTopic), - "operations": resources_core.FormatString(plan.Operations), - "group": resources_core.FormatString(plan.Group), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_user" == "" { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "operations": resources_core.FormatString(plan.Operations), - "group": resources_core.FormatString(plan.Group), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "username": resources_core.FormatString(plan.Username), - }) - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_user", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.KafkaID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *KafkaUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/117_nifi_resource.go b/generated/prod/go/117_nifi_resource.go deleted file mode 100644 index 4f1ce03..0000000 --- a/generated/prod/go/117_nifi_resource.go +++ /dev/null @@ -1,461 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nifi -// Service ID: 117 - -var _ resource.Resource = &NifiResource{} -var _ resource.ResourceWithModifyPlan = &NifiResource{} -var _ resource.ResourceWithImportState = &NifiResource{} - -type NifiResource struct { - client *core.UniversalClient -} - -type NifiModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - KafkaUid types.String `tfsdk:"kafka_uid"` - NameTopic types.String `tfsdk:"name_topic"` - Partitions types.Int64 `tfsdk:"partitions"` - Replicas types.Int64 `tfsdk:"replicas"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNifiResource() resource.Resource { - return &NifiResource{} -} - -func (r *NifiResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nifi" -} - -func (r *NifiResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "kafka_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать кластер из списка Не изменяется после создания."}, - "name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events` Не изменяется после создания."}, - "partitions": schema.Int64Attribute{Required: true, MarkdownDescription: "Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50`"}, - "replicas": schema.Int64Attribute{Required: true, MarkdownDescription: "Количество партиций ≤ (число брокеров). Пример `2`"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NifiResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NifiModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, plan.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != plan.KafkaUid.ValueString() { - plan.KafkaUid = types.StringValue(resolvedKafkaUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - if plan.KafkaUid.ValueString() != state.KafkaUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить kafka_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NameTopic.IsNull() && !plan.NameTopic.IsUnknown() && !state.NameTopic.IsNull() && !state.NameTopic.IsUnknown() { - if plan.NameTopic.ValueString() != state.NameTopic.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить name_topic", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.KafkaUid.IsNull() || config.KafkaUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if config.NameTopic.IsNull() || config.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if config.Partitions.IsNull() || config.Partitions.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "partitions is required.") - return - } - if config.Replicas.IsNull() || config.Replicas.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "replicas is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.KafkaUid.IsNull() && !config.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, config.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != config.KafkaUid.ValueString() { - config.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - params := map[int]string{ - 471: resources_core.FormatString(config.KafkaUid), - 472: resources_core.FormatInt64(config.Partitions), - 473: resources_core.FormatInt64(config.Replicas), - 474: resources_core.FormatString(config.NameTopic), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 117, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NifiResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.KafkaUid.IsNull() || data.KafkaUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if data.NameTopic.IsNull() || data.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if data.Partitions.IsNull() || data.Partitions.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "partitions is required.") - return - } - if data.Replicas.IsNull() || data.Replicas.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "replicas is required.") - return - } - if !data.KafkaUid.IsNull() && !data.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, data.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedKafkaUid != "" && resolvedKafkaUid != data.KafkaUid.ValueString() { - data.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 117, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 471: resources_core.FormatString(data.KafkaUid), - 472: resources_core.FormatInt64(data.Partitions), - 473: resources_core.FormatInt64(data.Replicas), - 474: resources_core.FormatString(data.NameTopic), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 117, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 117, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "nameTopic", Field: "NameTopic", Type: "string"}, - {Code: "partitions", Field: "Partitions", Type: "int64"}, - {Code: "replicas", Field: "Replicas", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NifiResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 117, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "nameTopic", Field: "NameTopic", Type: "string"}, - {Code: "partitions", Field: "Partitions", Type: "int64"}, - {Code: "replicas", Field: "Replicas", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, newState.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != newState.KafkaUid.ValueString() { - newState.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NifiResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NifiModel - var state NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.Partitions.IsNull() != state.Partitions.IsNull() || plan.Partitions.IsUnknown() != state.Partitions.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.Partitions.IsNull() && !plan.Partitions.IsUnknown() && !state.Partitions.IsNull() && !state.Partitions.IsUnknown() { - if plan.Partitions.ValueInt64() != state.Partitions.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.Replicas.IsNull() != state.Replicas.IsNull() || plan.Replicas.IsUnknown() != state.Replicas.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.Replicas.IsNull() && !plan.Replicas.IsUnknown() && !state.Replicas.IsNull() && !state.Replicas.IsUnknown() { - if plan.Replicas.ValueInt64() != state.Replicas.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 477: resources_core.FormatInt64(plan.Partitions), - 478: resources_core.FormatInt64(plan.Replicas), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 117, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "nameTopic", Field: "NameTopic", Type: "string"}, - {Code: "partitions", Field: "Partitions", Type: "int64"}, - {Code: "replicas", Field: "Replicas", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NifiResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NifiResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NifiResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/119_akhq_resource.go b/generated/prod/go/119_akhq_resource.go deleted file mode 100644 index 71a69ec..0000000 --- a/generated/prod/go/119_akhq_resource.go +++ /dev/null @@ -1,485 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: akhq -// Service ID: 119 - -var _ resource.Resource = &AkhqResource{} -var _ resource.ResourceWithModifyPlan = &AkhqResource{} -var _ resource.ResourceWithImportState = &AkhqResource{} - -type AkhqResource struct { - client *core.UniversalClient -} - -type AkhqModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - KafkaUid types.String `tfsdk:"kafka_uid"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewAkhqResource() resource.Resource { - return &AkhqResource{} -} - -func (r *AkhqResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_akhq" -} - -func (r *AkhqResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "kafka_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать кластер из списка"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Пример: `1000` Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Пример: `1024` Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *AkhqResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *AkhqModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, plan.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != plan.KafkaUid.ValueString() { - plan.KafkaUid = types.StringValue(resolvedKafkaUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() || config.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.KafkaUid.IsNull() || config.KafkaUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.KafkaUid.IsNull() && !config.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, config.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != config.KafkaUid.ValueString() { - config.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - params := map[int]string{ - 550: resources_core.FormatString(config.ResourceRealm), - 551: resources_core.FormatInt64(config.ResourceMemory), - 552: resources_core.FormatInt64(config.ResourceCPU), - 553: resources_core.FormatString(config.Domain), - 554: resources_core.FormatInt64(config.ResourceInstances), - 555: resources_core.FormatString(config.KafkaUid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 119, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *AkhqResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.KafkaUid.IsNull() || data.KafkaUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if !data.KafkaUid.IsNull() && !data.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, data.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedKafkaUid != "" && resolvedKafkaUid != data.KafkaUid.ValueString() { - data.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 119, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 550: resources_core.FormatString(data.ResourceRealm), - 551: resources_core.FormatInt64(data.ResourceMemory), - 552: resources_core.FormatInt64(data.ResourceCPU), - 553: resources_core.FormatString(data.Domain), - 554: resources_core.FormatInt64(data.ResourceInstances), - 555: resources_core.FormatString(data.KafkaUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 119, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 119, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *AkhqResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 119, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, newState.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != newState.KafkaUid.ValueString() { - newState.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *AkhqResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan AkhqModel - var state AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.KafkaUid.IsNull() != state.KafkaUid.IsNull() || plan.KafkaUid.IsUnknown() != state.KafkaUid.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - if plan.KafkaUid.ValueString() != state.KafkaUid.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 565: resources_core.FormatString(plan.KafkaUid), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 119, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *AkhqResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *AkhqResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *AkhqResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/120_clickhouse_database_resource.go b/generated/prod/go/120_clickhouse_database_resource.go deleted file mode 100644 index fd2d91e..0000000 --- a/generated/prod/go/120_clickhouse_database_resource.go +++ /dev/null @@ -1,339 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Subresource: database - -var _ resource.Resource = &ClickhouseDatabaseResource{} - -// ClickhouseDatabaseResource manages a subresource via operations. -type ClickhouseDatabaseResource struct { - client *core.UniversalClient -} - -type ClickhouseDatabaseModel struct { - ID types.String `tfsdk:"id"` - ClickhouseID types.String `tfsdk:"clickhouse_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - DatabaseName types.String `tfsdk:"database_name"` -} - -func NewClickhouseDatabaseResource() resource.Resource { - return &ClickhouseDatabaseResource{} -} - -func (r *ClickhouseDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse_database" -} - -func (r *ClickhouseDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "clickhouse_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "database_name": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `db01` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan ClickhouseDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.DatabaseName.IsNull() || plan.DatabaseName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "database_name is required.") - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - } - identityCodes := []string{ - "databaseName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(plan.DatabaseName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_database" == "" { - return - } - - instanceUID := strings.TrimSpace(state.ClickhouseID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "databaseName": resources_core.FormatString(state.DatabaseName), - } - identityCodes := []string{ - "databaseName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "databaseName": resources_core.FormatString(state.DatabaseName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_database", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *ClickhouseDatabaseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/120_clickhouse_resource.go b/generated/prod/go/120_clickhouse_resource.go deleted file mode 100644 index 6245b18..0000000 --- a/generated/prod/go/120_clickhouse_resource.go +++ /dev/null @@ -1,617 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Service ID: 120 - -var _ resource.Resource = &ClickhouseResource{} -var _ resource.ResourceWithModifyPlan = &ClickhouseResource{} -var _ resource.ResourceWithImportState = &ClickhouseResource{} - -type ClickhouseResource struct { - client *core.UniversalClient -} - -type ClickhouseModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AppVersion types.String `tfsdk:"app_version"` - ExtBACKUPNUMTORETAIN types.Int64 `tfsdk:"ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n"` - ExtBACKUPSCHEDULE types.String `tfsdk:"ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedCreateKeeper types.Bool `tfsdk:"need_create_keeper"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceCPUKeeper types.Int64 `tfsdk:"resource_c_p_u_keeper"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceInstancesKeeper types.Int64 `tfsdk:"resource_instances_keeper"` - ResourceInstancesShards types.Int64 `tfsdk:"resource_instances_shards"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceMemoryKeeper types.Int64 `tfsdk:"resource_memory_keeper"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewClickhouseResource() resource.Resource { - return &ClickhouseResource{} -} - -func (r *ClickhouseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse" -} - -func (r *ClickhouseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("25.10"), MarkdownDescription: "Версия `clickhouse-server`"}, - "ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(7), MarkdownDescription: "Пример: `7`"}, - "ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("0 0 * * *"), MarkdownDescription: "Принимает формат `CRON`"}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"}, - "need_create_keeper": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Необходим для кластеризации ClickHouse"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Позволяет подключиться извне к ClickHouse"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Пример: `1000`"}, - "resource_c_p_u_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(50), MarkdownDescription: "Пример: `100`"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Пример: `100`"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `3`"}, - "resource_instances_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"}, - "resource_instances_shards": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1536), MarkdownDescription: "Пример: `2048`"}, - "resource_memory_keeper": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(152), MarkdownDescription: "Пример: `256`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Кластер Kubernetes в котором будет развёрнуто приложение Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *ClickhouseModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() { - plan.S3Uid = types.StringValue(resolvedS3Uid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - if plan.S3Uid.ValueString() != state.S3Uid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 572: resources_core.FormatString(config.ResourceRealm), - 573: resources_core.FormatString(config.S3Uid), - 574: resources_core.FormatInt64(config.ResourceInstances), - 575: resources_core.FormatInt64(config.ResourceInstancesShards), - 576: resources_core.FormatInt64(config.ResourceCPU), - 577: resources_core.FormatInt64(config.ResourceMemory), - 578: resources_core.FormatString(config.AppVersion), - 579: resources_core.FormatInt64(config.ResourceDisk), - 580: resources_core.FormatBool(config.NeedExternalAddressMaster), - 581: resources_core.FormatString(config.IpSpaceNameMaster), - 582: resources_core.FormatBool(config.NeedCreateKeeper), - 583: resources_core.FormatInt64(config.ResourceCPUKeeper), - 584: resources_core.FormatInt64(config.ResourceMemoryKeeper), - 585: resources_core.FormatInt64(config.ResourceInstancesKeeper), - 586: resources_core.FormatString(config.ExtBACKUPSCHEDULE), - 587: resources_core.FormatInt64(config.ExtBACKUPNUMTORETAIN), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 120, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *ClickhouseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 120, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 572: resources_core.FormatString(data.ResourceRealm), - 573: resources_core.FormatString(data.S3Uid), - 574: resources_core.FormatInt64(data.ResourceInstances), - 575: resources_core.FormatInt64(data.ResourceInstancesShards), - 576: resources_core.FormatInt64(data.ResourceCPU), - 577: resources_core.FormatInt64(data.ResourceMemory), - 578: resources_core.FormatString(data.AppVersion), - 579: resources_core.FormatInt64(data.ResourceDisk), - 580: resources_core.FormatBool(data.NeedExternalAddressMaster), - 581: resources_core.FormatString(data.IpSpaceNameMaster), - 582: resources_core.FormatBool(data.NeedCreateKeeper), - 583: resources_core.FormatInt64(data.ResourceCPUKeeper), - 584: resources_core.FormatInt64(data.ResourceMemoryKeeper), - 585: resources_core.FormatInt64(data.ResourceInstancesKeeper), - 586: resources_core.FormatString(data.ExtBACKUPSCHEDULE), - 587: resources_core.FormatInt64(data.ExtBACKUPNUMTORETAIN), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 120, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 120, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"}, - {Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 120, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"}, - {Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *ClickhouseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseModel - var state ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstancesShards.IsNull() != state.ResourceInstancesShards.IsNull() || plan.ResourceInstancesShards.IsUnknown() != state.ResourceInstancesShards.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstancesShards.IsNull() && !plan.ResourceInstancesShards.IsUnknown() && !state.ResourceInstancesShards.IsNull() && !state.ResourceInstancesShards.IsUnknown() { - if plan.ResourceInstancesShards.ValueInt64() != state.ResourceInstancesShards.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedCreateKeeper.IsNull() != state.NeedCreateKeeper.IsNull() || plan.NeedCreateKeeper.IsUnknown() != state.NeedCreateKeeper.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedCreateKeeper.IsNull() && !plan.NeedCreateKeeper.IsUnknown() && !state.NeedCreateKeeper.IsNull() && !state.NeedCreateKeeper.IsUnknown() { - if plan.NeedCreateKeeper.ValueBool() != state.NeedCreateKeeper.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPUKeeper.IsNull() != state.ResourceCPUKeeper.IsNull() || plan.ResourceCPUKeeper.IsUnknown() != state.ResourceCPUKeeper.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPUKeeper.IsNull() && !plan.ResourceCPUKeeper.IsUnknown() && !state.ResourceCPUKeeper.IsNull() && !state.ResourceCPUKeeper.IsUnknown() { - if plan.ResourceCPUKeeper.ValueInt64() != state.ResourceCPUKeeper.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemoryKeeper.IsNull() != state.ResourceMemoryKeeper.IsNull() || plan.ResourceMemoryKeeper.IsUnknown() != state.ResourceMemoryKeeper.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemoryKeeper.IsNull() && !plan.ResourceMemoryKeeper.IsUnknown() && !state.ResourceMemoryKeeper.IsNull() && !state.ResourceMemoryKeeper.IsUnknown() { - if plan.ResourceMemoryKeeper.ValueInt64() != state.ResourceMemoryKeeper.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstancesKeeper.IsNull() != state.ResourceInstancesKeeper.IsNull() || plan.ResourceInstancesKeeper.IsUnknown() != state.ResourceInstancesKeeper.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstancesKeeper.IsNull() && !plan.ResourceInstancesKeeper.IsUnknown() && !state.ResourceInstancesKeeper.IsNull() && !state.ResourceInstancesKeeper.IsUnknown() { - if plan.ResourceInstancesKeeper.ValueInt64() != state.ResourceInstancesKeeper.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPSCHEDULE.IsNull() != state.ExtBACKUPSCHEDULE.IsNull() || plan.ExtBACKUPSCHEDULE.IsUnknown() != state.ExtBACKUPSCHEDULE.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPSCHEDULE.IsNull() && !plan.ExtBACKUPSCHEDULE.IsUnknown() && !state.ExtBACKUPSCHEDULE.IsNull() && !state.ExtBACKUPSCHEDULE.IsUnknown() { - if plan.ExtBACKUPSCHEDULE.ValueString() != state.ExtBACKUPSCHEDULE.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPNUMTORETAIN.IsNull() != state.ExtBACKUPNUMTORETAIN.IsNull() || plan.ExtBACKUPNUMTORETAIN.IsUnknown() != state.ExtBACKUPNUMTORETAIN.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPNUMTORETAIN.IsNull() && !plan.ExtBACKUPNUMTORETAIN.IsUnknown() && !state.ExtBACKUPNUMTORETAIN.IsNull() && !state.ExtBACKUPNUMTORETAIN.IsUnknown() { - if plan.ExtBACKUPNUMTORETAIN.ValueInt64() != state.ExtBACKUPNUMTORETAIN.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 603: resources_core.FormatInt64(plan.ResourceInstances), - 604: resources_core.FormatInt64(plan.ResourceInstancesShards), - 605: resources_core.FormatInt64(plan.ResourceCPU), - 606: resources_core.FormatInt64(plan.ResourceMemory), - 607: resources_core.FormatString(plan.AppVersion), - 608: resources_core.FormatInt64(plan.ResourceDisk), - 609: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 610: resources_core.FormatString(plan.IpSpaceNameMaster), - 611: resources_core.FormatBool(plan.NeedCreateKeeper), - 612: resources_core.FormatInt64(plan.ResourceCPUKeeper), - 613: resources_core.FormatInt64(plan.ResourceMemoryKeeper), - 614: resources_core.FormatInt64(plan.ResourceInstancesKeeper), - 615: resources_core.FormatString(plan.ExtBACKUPSCHEDULE), - 616: resources_core.FormatInt64(plan.ExtBACKUPNUMTORETAIN), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 120, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needCreateKeeper", Field: "NeedCreateKeeper", Type: "bool"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceCPUKeeper", Field: "ResourceCPUKeeper", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceInstancesKeeper", Field: "ResourceInstancesKeeper", Type: "int64"}, - {Code: "resourceInstancesShards", Field: "ResourceInstancesShards", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceMemoryKeeper", Field: "ResourceMemoryKeeper", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *ClickhouseResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *ClickhouseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/120_clickhouse_user_resource.go b/generated/prod/go/120_clickhouse_user_resource.go deleted file mode 100644 index 4eb5176..0000000 --- a/generated/prod/go/120_clickhouse_user_resource.go +++ /dev/null @@ -1,356 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Subresource: user - -var _ resource.Resource = &ClickhouseUserResource{} - -// ClickhouseUserResource manages a subresource via operations. -type ClickhouseUserResource struct { - client *core.UniversalClient -} - -type ClickhouseUserModel struct { - ID types.String `tfsdk:"id"` - ClickhouseID types.String `tfsdk:"clickhouse_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AccessHosts types.String `tfsdk:"access_hosts"` - DatabaseName types.String `tfsdk:"database_name"` - Username types.String `tfsdk:"username"` -} - -func NewClickhouseUserResource() resource.Resource { - return &ClickhouseUserResource{} -} - -func (r *ClickhouseUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse_user" -} - -func (r *ClickhouseUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "clickhouse_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "access_hosts": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("::/0"), MarkdownDescription: "Пример: `::/0` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "database_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[\"database\"]"), MarkdownDescription: "Необходимо указать массив существующих баз Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `myusername` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan ClickhouseUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "accessHosts", - "databaseName", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "databaseName": resources_core.FormatString(plan.DatabaseName), - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.ClickhouseID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(state.AccessHosts), - "databaseName": resources_core.FormatString(state.DatabaseName), - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "accessHosts", - "databaseName", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *ClickhouseUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/12_s3_resource.go b/generated/prod/go/12_s3_resource.go deleted file mode 100644 index 5387016..0000000 --- a/generated/prod/go/12_s3_resource.go +++ /dev/null @@ -1,401 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3 -// Service ID: 12 - -var _ resource.Resource = &S3Resource{} -var _ resource.ResourceWithModifyPlan = &S3Resource{} -var _ resource.ResourceWithImportState = &S3Resource{} - -type S3Resource struct { - client *core.UniversalClient -} - -type S3Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - DisplayName types.String `tfsdk:"display_name"` - MaxBucketsPerUser types.Int64 `tfsdk:"max_buckets_per_user"` - MaxObjectsPerBucket types.Int64 `tfsdk:"max_objects_per_bucket"` - MaxSizeGbPerUser types.Int64 `tfsdk:"max_size_gb_per_user"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewS3Resource() resource.Resource { - return &S3Resource{} -} - -func (r *S3Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3" -} - -func (r *S3Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "display_name": schema.StringAttribute{Required: true, MarkdownDescription: "Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента Не изменяется после создания."}, - "max_buckets_per_user": schema.Int64Attribute{Optional: true, MarkdownDescription: "Квота на пользователя. Количество бакетов пользователя. Передаём руками"}, - "max_objects_per_bucket": schema.Int64Attribute{Optional: true, MarkdownDescription: "Квота на бакет. Кол-во объектов. Передаём руками"}, - "max_size_gb_per_user": schema.Int64Attribute{Optional: true, MarkdownDescription: "maxSizeGb. Передаём руками"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *S3Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.DisplayName.IsNull() && !plan.DisplayName.IsUnknown() && !state.DisplayName.IsNull() && !state.DisplayName.IsUnknown() { - if plan.DisplayName.ValueString() != state.DisplayName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить display_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.DisplayName.IsNull() || config.DisplayName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "display_name is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 163: resources_core.FormatString(config.ResourceRealm), - 320: resources_core.FormatString(config.DisplayName), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 12, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *S3Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.DisplayName.IsNull() || data.DisplayName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "display_name is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 12, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 163: resources_core.FormatString(data.ResourceRealm), - 320: resources_core.FormatString(data.DisplayName), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 12, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 12, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 12, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *S3Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3Model - var state S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.MaxSizeGbPerUser.IsNull() != state.MaxSizeGbPerUser.IsNull() || plan.MaxSizeGbPerUser.IsUnknown() != state.MaxSizeGbPerUser.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxSizeGbPerUser.IsNull() && !plan.MaxSizeGbPerUser.IsUnknown() && !state.MaxSizeGbPerUser.IsNull() && !state.MaxSizeGbPerUser.IsUnknown() { - if plan.MaxSizeGbPerUser.ValueInt64() != state.MaxSizeGbPerUser.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MaxObjectsPerBucket.IsNull() != state.MaxObjectsPerBucket.IsNull() || plan.MaxObjectsPerBucket.IsUnknown() != state.MaxObjectsPerBucket.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxObjectsPerBucket.IsNull() && !plan.MaxObjectsPerBucket.IsUnknown() && !state.MaxObjectsPerBucket.IsNull() && !state.MaxObjectsPerBucket.IsUnknown() { - if plan.MaxObjectsPerBucket.ValueInt64() != state.MaxObjectsPerBucket.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MaxBucketsPerUser.IsNull() != state.MaxBucketsPerUser.IsNull() || plan.MaxBucketsPerUser.IsUnknown() != state.MaxBucketsPerUser.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxBucketsPerUser.IsNull() && !plan.MaxBucketsPerUser.IsUnknown() && !state.MaxBucketsPerUser.IsNull() && !state.MaxBucketsPerUser.IsUnknown() { - if plan.MaxBucketsPerUser.ValueInt64() != state.MaxBucketsPerUser.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 50: resources_core.FormatInt64(plan.MaxSizeGbPerUser), - 51: resources_core.FormatInt64(plan.MaxObjectsPerBucket), - 52: resources_core.FormatInt64(plan.MaxBucketsPerUser), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 12, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *S3Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *S3Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/12_s3_sub_user_resource.go b/generated/prod/go/12_s3_sub_user_resource.go deleted file mode 100644 index 66cc0ab..0000000 --- a/generated/prod/go/12_s3_sub_user_resource.go +++ /dev/null @@ -1,351 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3 -// Subresource: sub_user - -var _ resource.Resource = &S3SubUserResource{} - -// S3SubUserResource manages a subresource via operations. -type S3SubUserResource struct { - client *core.UniversalClient -} - -type S3SubUserModel struct { - ID types.String `tfsdk:"id"` - S3ID types.String `tfsdk:"s3_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - SubUserAccess types.String `tfsdk:"sub_user_access"` - SubUserName types.String `tfsdk:"sub_user_name"` -} - -func NewS3SubUserResource() resource.Resource { - return &S3SubUserResource{} -} - -func (r *S3SubUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3_sub_user" -} - -func (r *S3SubUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "s3_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "sub_user_access": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "sub_user_name": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3SubUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan S3SubUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.SubUserAccess.IsNull() || plan.SubUserAccess.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "sub_user_access is required.") - return - } - if plan.SubUserName.IsNull() || plan.SubUserName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "sub_user_name is required.") - return - } - - instanceUID := strings.TrimSpace(plan.S3ID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - "subUserName": resources_core.FormatString(plan.SubUserName), - } - identityCodes := []string{ - "subUserAccess", - "subUserName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("sub_user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "subUserName": resources_core.FormatString(plan.SubUserName), - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_sub_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_sub_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *S3SubUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3SubUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3SubUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.S3ID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - "subUserName": resources_core.FormatString(plan.SubUserName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *S3SubUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_sub_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.S3ID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(state.SubUserAccess), - "subUserName": resources_core.FormatString(state.SubUserName), - } - identityCodes := []string{ - "subUserAccess", - "subUserName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("sub_user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "subUserName": resources_core.FormatString(state.SubUserName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_sub_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *S3SubUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/13_s3bucket_resource.go b/generated/prod/go/13_s3bucket_resource.go deleted file mode 100644 index 37210ea..0000000 --- a/generated/prod/go/13_s3bucket_resource.go +++ /dev/null @@ -1,439 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3bucket -// Service ID: 13 - -var _ resource.Resource = &S3bucketResource{} -var _ resource.ResourceWithModifyPlan = &S3bucketResource{} -var _ resource.ResourceWithImportState = &S3bucketResource{} - -type S3bucketResource struct { - client *core.UniversalClient -} - -type S3bucketModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - BucketName types.String `tfsdk:"bucket_name"` - CorsAll types.Bool `tfsdk:"cors_all"` - ListAll types.Bool `tfsdk:"list_all"` - MaxSize types.String `tfsdk:"max_size"` - Placement types.String `tfsdk:"placement"` - ReadAll types.Bool `tfsdk:"read_all"` - S3UserUid types.String `tfsdk:"s3_user_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewS3bucketResource() resource.Resource { - return &S3bucketResource{} -} - -func (r *S3bucketResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3bucket" -} - -func (r *S3bucketResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "bucket_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя бакета s3 Не изменяется после создания."}, - "cors_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS Не изменяется после создания."}, - "list_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. Не изменяется после создания."}, - "max_size": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("-1"), MarkdownDescription: "Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes Не изменяется после создания."}, - "placement": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("HOT"), MarkdownDescription: "Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения Не изменяется после создания."}, - "read_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. Не изменяется после создания."}, - "s3_user_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UID Корневой услуги S3. На основе него будет создан бакет. Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3bucketResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *S3bucketModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3UserUid.IsNull() && !plan.S3UserUid.IsUnknown() { - resolvedS3UserUid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3UserUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_user_uid", err.Error()) - } else if resolvedS3UserUid != "" && resolvedS3UserUid != plan.S3UserUid.ValueString() { - plan.S3UserUid = types.StringValue(resolvedS3UserUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.BucketName.IsNull() && !plan.BucketName.IsUnknown() && !state.BucketName.IsNull() && !state.BucketName.IsUnknown() { - if plan.BucketName.ValueString() != state.BucketName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить bucket_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.CorsAll.IsNull() && !plan.CorsAll.IsUnknown() && !state.CorsAll.IsNull() && !state.CorsAll.IsUnknown() { - if plan.CorsAll.ValueBool() != state.CorsAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить cors_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ListAll.IsNull() && !plan.ListAll.IsUnknown() && !state.ListAll.IsNull() && !state.ListAll.IsUnknown() { - if plan.ListAll.ValueBool() != state.ListAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить list_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MaxSize.IsNull() && !plan.MaxSize.IsUnknown() && !state.MaxSize.IsNull() && !state.MaxSize.IsUnknown() { - if plan.MaxSize.ValueString() != state.MaxSize.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить max_size", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Placement.IsNull() && !plan.Placement.IsUnknown() && !state.Placement.IsNull() && !state.Placement.IsUnknown() { - if plan.Placement.ValueString() != state.Placement.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить placement", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ReadAll.IsNull() && !plan.ReadAll.IsUnknown() && !state.ReadAll.IsNull() && !state.ReadAll.IsUnknown() { - if plan.ReadAll.ValueBool() != state.ReadAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить read_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3UserUid.IsNull() && !plan.S3UserUid.IsUnknown() && !state.S3UserUid.IsNull() && !state.S3UserUid.IsUnknown() { - if plan.S3UserUid.ValueString() != state.S3UserUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_user_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.BucketName.IsNull() || config.BucketName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "bucket_name is required.") - return - } - if config.S3UserUid.IsNull() || config.S3UserUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_user_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3UserUid.IsNull() && !config.S3UserUid.IsUnknown() { - resolvedS3UserUid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3UserUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_user_uid", err.Error()) - } else if resolvedS3UserUid != "" && resolvedS3UserUid != config.S3UserUid.ValueString() { - config.S3UserUid = types.StringValue(resolvedS3UserUid) - } - } - params := map[int]string{ - 124: resources_core.FormatString(config.S3UserUid), - 125: resources_core.FormatString(config.BucketName), - 126: resources_core.FormatString(config.MaxSize), - 127: resources_core.FormatBool(config.ReadAll), - 128: resources_core.FormatBool(config.ListAll), - 129: resources_core.FormatBool(config.CorsAll), - 130: resources_core.FormatString(config.Placement), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 13, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *S3bucketResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.BucketName.IsNull() || data.BucketName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "bucket_name is required.") - return - } - if data.S3UserUid.IsNull() || data.S3UserUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_user_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 13, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 124: resources_core.FormatString(data.S3UserUid), - 125: resources_core.FormatString(data.BucketName), - 126: resources_core.FormatString(data.MaxSize), - 127: resources_core.FormatBool(data.ReadAll), - 128: resources_core.FormatBool(data.ListAll), - 129: resources_core.FormatBool(data.CorsAll), - 130: resources_core.FormatString(data.Placement), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 13, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 13, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3bucketResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 13, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *S3bucketResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3bucketModel - var state S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 13, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3bucketResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *S3bucketResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *S3bucketResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/149_valo_tenant_resource.go b/generated/prod/go/149_valo_tenant_resource.go deleted file mode 100644 index 9aef80e..0000000 --- a/generated/prod/go/149_valo_tenant_resource.go +++ /dev/null @@ -1,398 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: valo_tenant -// Service ID: 149 - -var _ resource.Resource = &ValoTenantResource{} -var _ resource.ResourceWithModifyPlan = &ValoTenantResource{} -var _ resource.ResourceWithImportState = &ValoTenantResource{} - -type ValoTenantResource struct { - client *core.UniversalClient -} - -type ValoTenantModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Storage types.Int64 `tfsdk:"s3_storage"` - ValoOptions types.String `tfsdk:"valo_options"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewValoTenantResource() resource.Resource { - return &ValoTenantResource{} -} - -func (r *ValoTenantResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_valo_tenant" -} - -func (r *ValoTenantResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Будет добавлено в зону valo.ngcloud.ru Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "s3_storage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Параметр указывается в `Gb`"}, - "valo_options": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{}")}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ValoTenantResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *ValoTenantModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() || config.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 655: resources_core.FormatString(config.ResourceRealm), - 656: resources_core.FormatString(config.Domain), - 657: resources_core.FormatString(config.ValoOptions), - 658: resources_core.FormatInt64(config.S3Storage), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 149, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *ValoTenantResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 149, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 655: resources_core.FormatString(data.ResourceRealm), - 656: resources_core.FormatString(data.Domain), - 657: resources_core.FormatString(data.ValoOptions), - 658: resources_core.FormatInt64(data.S3Storage), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 149, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 149, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ValoTenantResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 149, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *ValoTenantResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ValoTenantModel - var state ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ValoOptions.IsNull() != state.ValoOptions.IsNull() || plan.ValoOptions.IsUnknown() != state.ValoOptions.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ValoOptions.IsNull() && !plan.ValoOptions.IsUnknown() && !state.ValoOptions.IsNull() && !state.ValoOptions.IsUnknown() { - if plan.ValoOptions.ValueString() != state.ValoOptions.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.S3Storage.IsNull() != state.S3Storage.IsNull() || plan.S3Storage.IsUnknown() != state.S3Storage.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.S3Storage.IsNull() && !plan.S3Storage.IsUnknown() && !state.S3Storage.IsNull() && !state.S3Storage.IsUnknown() { - if plan.S3Storage.ValueInt64() != state.S3Storage.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 659: resources_core.FormatString(plan.ValoOptions), - 660: resources_core.FormatInt64(plan.S3Storage), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 149, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ValoTenantResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *ValoTenantResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *ValoTenantResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/150_k8s_sthutrval_cluster_reconcile_action.go b/generated/prod/go/150_k8s_sthutrval_cluster_reconcile_action.go deleted file mode 100644 index 40aa238..0000000 --- a/generated/prod/go/150_k8s_sthutrval_cluster_reconcile_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_sthutrval_cluster -// Action: reconcile - -var _ resource.Resource = &K8sSthutrvalClusterReconcileResource{} - -// K8sSthutrvalClusterReconcileResource triggers a one-time action. -type K8sSthutrvalClusterReconcileResource struct { - client *core.UniversalClient -} - -type K8sSthutrvalClusterReconcileModel struct { - ID types.String `tfsdk:"id"` - K8sSthutrvalClusterID types.String `tfsdk:"k8s_sthutrval_cluster_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewK8sSthutrvalClusterReconcileResource() resource.Resource { - return &K8sSthutrvalClusterReconcileResource{} -} - -func (r *K8sSthutrvalClusterReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_sthutrval_cluster_reconcile" -} - -func (r *K8sSthutrvalClusterReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_sthutrval_cluster_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sSthutrvalClusterReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sSthutrvalClusterReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sSthutrvalClusterReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sSthutrvalClusterReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sSthutrvalClusterReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/150_k8s_sthutrval_cluster_resource.go b/generated/prod/go/150_k8s_sthutrval_cluster_resource.go deleted file mode 100644 index 53853b4..0000000 --- a/generated/prod/go/150_k8s_sthutrval_cluster_resource.go +++ /dev/null @@ -1,667 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_sthutrval_cluster -// Service ID: 150 - -var _ resource.Resource = &K8sSthutrvalClusterResource{} -var _ resource.ResourceWithModifyPlan = &K8sSthutrvalClusterResource{} -var _ resource.ResourceWithImportState = &K8sSthutrvalClusterResource{} - -type K8sSthutrvalClusterResource struct { - client *core.UniversalClient -} - -type K8sSthutrvalClusterModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AccessIpListAPI types.String `tfsdk:"access_ip_list_a_p_i"` - AccessIpListIngress types.String `tfsdk:"access_ip_list_ingress"` - AppVersion types.String `tfsdk:"app_version"` - ClusterName types.String `tfsdk:"cluster_name"` - ControlPlaneCount types.Int64 `tfsdk:"control_plane_count"` - ControlPlaneSizingDisk types.Int64 `tfsdk:"control_plane_sizing_disk"` - ControlPlaneSizingPolicy types.String `tfsdk:"control_plane_sizing_policy"` - NeedExternalAddressAPI types.Bool `tfsdk:"need_external_address_a_p_i"` - NeedExternalAddressIngress types.Bool `tfsdk:"need_external_address_ingress"` - NsxtUid types.String `tfsdk:"nsxt_uid"` - VdcUid types.String `tfsdk:"vdc_uid"` - WorkersCount types.Int64 `tfsdk:"workers_count"` - WorkersSizingDisk types.Int64 `tfsdk:"workers_sizing_disk"` - WorkersSizingPolicy types.String `tfsdk:"workers_sizing_policy"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewK8sSthutrvalClusterResource() resource.Resource { - return &K8sSthutrvalClusterResource{} -} - -func (r *K8sSthutrvalClusterResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_sthutrval_cluster" -} - -func (r *K8sSthutrvalClusterResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "access_ip_list_a_p_i": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[]"), MarkdownDescription: "Access IP List для подключения к Kubernetes API. Указывается массив. Если передан пустой массив, доступ выделяется всем"}, - "access_ip_list_ingress": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[]"), MarkdownDescription: "Access IP List для подключения к Ingress. Указывается массив. Если передан пустой массив, доступ выделяется всем"}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("2.12.1"), MarkdownDescription: "Версия Штурвал (не является версией Kubernetes)"}, - "cluster_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("example1"), MarkdownDescription: "Наименование кластера Kubernetes. Имя будет использоваться в fqdn (svc.$CLUSTER_NAME) Не изменяется после создания."}, - "control_plane_count": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1)}, - "control_plane_sizing_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(30), MarkdownDescription: "Настройка Control Plane. Disk (Gb)"}, - "control_plane_sizing_policy": schema.StringAttribute{Required: true, MarkdownDescription: "Настройка Control Plane. CPU (шт) / MEM (gb).
Наверное, должна подтягиваться из свойств ресурсной платформы Не изменяется после создания."}, - "need_external_address_a_p_i": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Выделяет внешний IP для доступа к kubernetes API. Пока нельзя выставить false Не изменяется после создания."}, - "need_external_address_ingress": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Выделяет внешний IP для доступа к Ingress Не изменяется после создания."}, - "nsxt_uid": schema.StringAttribute{Required: true, MarkdownDescription: "InstanceUid nsxt. Nsxt должен быть создан Не изменяется после создания."}, - "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=21 (mapped to UUID in core) Не изменяется после создания."}, - "workers_count": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(2), MarkdownDescription: "Настройка workers. Кол-во нод"}, - "workers_sizing_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(40), MarkdownDescription: "Настройка workers. Disk (Gb)"}, - "workers_sizing_policy": schema.StringAttribute{Required: true, MarkdownDescription: "Настройка workers. CPU (шт) / MEM (gb) Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sSthutrvalClusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, plan.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != plan.NsxtUid.ValueString() { - plan.NsxtUid = types.StringValue(resolvedNsxtUid) - planChanged = true - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() { - plan.VdcUid = types.StringValue(resolvedVdcUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ClusterName.IsNull() && !plan.ClusterName.IsUnknown() && !state.ClusterName.IsNull() && !state.ClusterName.IsUnknown() { - if plan.ClusterName.ValueString() != state.ClusterName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить cluster_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ControlPlaneSizingPolicy.IsNull() && !plan.ControlPlaneSizingPolicy.IsUnknown() && !state.ControlPlaneSizingPolicy.IsNull() && !state.ControlPlaneSizingPolicy.IsUnknown() { - if plan.ControlPlaneSizingPolicy.ValueString() != state.ControlPlaneSizingPolicy.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить control_plane_sizing_policy", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressAPI.IsNull() && !plan.NeedExternalAddressAPI.IsUnknown() && !state.NeedExternalAddressAPI.IsNull() && !state.NeedExternalAddressAPI.IsUnknown() { - if plan.NeedExternalAddressAPI.ValueBool() != state.NeedExternalAddressAPI.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_a_p_i", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressIngress.IsNull() && !plan.NeedExternalAddressIngress.IsUnknown() && !state.NeedExternalAddressIngress.IsNull() && !state.NeedExternalAddressIngress.IsUnknown() { - if plan.NeedExternalAddressIngress.ValueBool() != state.NeedExternalAddressIngress.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_ingress", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - if plan.NsxtUid.ValueString() != state.NsxtUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить nsxt_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if plan.VdcUid.ValueString() != state.VdcUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.WorkersSizingPolicy.IsNull() && !plan.WorkersSizingPolicy.IsUnknown() && !state.WorkersSizingPolicy.IsNull() && !state.WorkersSizingPolicy.IsUnknown() { - if plan.WorkersSizingPolicy.ValueString() != state.WorkersSizingPolicy.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить workers_sizing_policy", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ControlPlaneSizingPolicy.IsNull() || config.ControlPlaneSizingPolicy.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "control_plane_sizing_policy is required.") - return - } - if config.NsxtUid.IsNull() || config.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if config.WorkersSizingPolicy.IsNull() || config.WorkersSizingPolicy.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "workers_sizing_policy is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.NsxtUid.IsNull() && !config.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, config.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != config.NsxtUid.ValueString() { - config.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 344: resources_core.FormatString(config.NsxtUid), - 345: resources_core.FormatString(config.ClusterName), - 346: resources_core.FormatString(config.ControlPlaneSizingPolicy), - 347: resources_core.FormatInt64(config.ControlPlaneSizingDisk), - 348: resources_core.FormatInt64(config.ControlPlaneCount), - 349: resources_core.FormatString(config.WorkersSizingPolicy), - 350: resources_core.FormatInt64(config.WorkersSizingDisk), - 351: resources_core.FormatInt64(config.WorkersCount), - 352: resources_core.FormatString(config.AppVersion), - 353: resources_core.FormatBool(config.NeedExternalAddressAPI), - 354: resources_core.FormatString(config.AccessIpListAPI), - 355: resources_core.FormatBool(config.NeedExternalAddressIngress), - 356: resources_core.FormatString(config.AccessIpListIngress), - 747: resources_core.FormatString(config.VdcUid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 150, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *K8sSthutrvalClusterResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ControlPlaneSizingPolicy.IsNull() || data.ControlPlaneSizingPolicy.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "control_plane_sizing_policy is required.") - return - } - if data.NsxtUid.IsNull() || data.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if data.WorkersSizingPolicy.IsNull() || data.WorkersSizingPolicy.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "workers_sizing_policy is required.") - return - } - if !data.NsxtUid.IsNull() && !data.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, data.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedNsxtUid != "" && resolvedNsxtUid != data.NsxtUid.ValueString() { - data.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 150, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 344: resources_core.FormatString(data.NsxtUid), - 345: resources_core.FormatString(data.ClusterName), - 346: resources_core.FormatString(data.ControlPlaneSizingPolicy), - 347: resources_core.FormatInt64(data.ControlPlaneSizingDisk), - 348: resources_core.FormatInt64(data.ControlPlaneCount), - 349: resources_core.FormatString(data.WorkersSizingPolicy), - 350: resources_core.FormatInt64(data.WorkersSizingDisk), - 351: resources_core.FormatInt64(data.WorkersCount), - 352: resources_core.FormatString(data.AppVersion), - 353: resources_core.FormatBool(data.NeedExternalAddressAPI), - 354: resources_core.FormatString(data.AccessIpListAPI), - 355: resources_core.FormatBool(data.NeedExternalAddressIngress), - 356: resources_core.FormatString(data.AccessIpListIngress), - 747: resources_core.FormatString(data.VdcUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 150, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 150, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpListAPI", Field: "AccessIpListAPI", Type: "string"}, - {Code: "accessIpListIngress", Field: "AccessIpListIngress", Type: "string"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "clusterName", Field: "ClusterName", Type: "string"}, - {Code: "controlPlaneCount", Field: "ControlPlaneCount", Type: "int64"}, - {Code: "controlPlaneSizingDisk", Field: "ControlPlaneSizingDisk", Type: "int64"}, - {Code: "controlPlaneSizingPolicy", Field: "ControlPlaneSizingPolicy", Type: "string"}, - {Code: "needExternalAddressAPI", Field: "NeedExternalAddressAPI", Type: "bool"}, - {Code: "needExternalAddressIngress", Field: "NeedExternalAddressIngress", Type: "bool"}, - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "workersCount", Field: "WorkersCount", Type: "int64"}, - {Code: "workersSizingDisk", Field: "WorkersSizingDisk", Type: "int64"}, - {Code: "workersSizingPolicy", Field: "WorkersSizingPolicy", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 150, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpListAPI", Field: "AccessIpListAPI", Type: "string"}, - {Code: "accessIpListIngress", Field: "AccessIpListIngress", Type: "string"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "clusterName", Field: "ClusterName", Type: "string"}, - {Code: "controlPlaneCount", Field: "ControlPlaneCount", Type: "int64"}, - {Code: "controlPlaneSizingDisk", Field: "ControlPlaneSizingDisk", Type: "int64"}, - {Code: "controlPlaneSizingPolicy", Field: "ControlPlaneSizingPolicy", Type: "string"}, - {Code: "needExternalAddressAPI", Field: "NeedExternalAddressAPI", Type: "bool"}, - {Code: "needExternalAddressIngress", Field: "NeedExternalAddressIngress", Type: "bool"}, - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "workersCount", Field: "WorkersCount", Type: "int64"}, - {Code: "workersSizingDisk", Field: "WorkersSizingDisk", Type: "int64"}, - {Code: "workersSizingPolicy", Field: "WorkersSizingPolicy", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.NsxtUid.IsNull() && !newState.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, newState.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != newState.NsxtUid.ValueString() { - newState.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *K8sSthutrvalClusterResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sSthutrvalClusterModel - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ControlPlaneCount.IsNull() != state.ControlPlaneCount.IsNull() || plan.ControlPlaneCount.IsUnknown() != state.ControlPlaneCount.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ControlPlaneCount.IsNull() && !plan.ControlPlaneCount.IsUnknown() && !state.ControlPlaneCount.IsNull() && !state.ControlPlaneCount.IsUnknown() { - if plan.ControlPlaneCount.ValueInt64() != state.ControlPlaneCount.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.WorkersCount.IsNull() != state.WorkersCount.IsNull() || plan.WorkersCount.IsUnknown() != state.WorkersCount.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.WorkersCount.IsNull() && !plan.WorkersCount.IsUnknown() && !state.WorkersCount.IsNull() && !state.WorkersCount.IsUnknown() { - if plan.WorkersCount.ValueInt64() != state.WorkersCount.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessIpListAPI.IsNull() != state.AccessIpListAPI.IsNull() || plan.AccessIpListAPI.IsUnknown() != state.AccessIpListAPI.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessIpListAPI.IsNull() && !plan.AccessIpListAPI.IsUnknown() && !state.AccessIpListAPI.IsNull() && !state.AccessIpListAPI.IsUnknown() { - if plan.AccessIpListAPI.ValueString() != state.AccessIpListAPI.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessIpListIngress.IsNull() != state.AccessIpListIngress.IsNull() || plan.AccessIpListIngress.IsUnknown() != state.AccessIpListIngress.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessIpListIngress.IsNull() && !plan.AccessIpListIngress.IsUnknown() && !state.AccessIpListIngress.IsNull() && !state.AccessIpListIngress.IsUnknown() { - if plan.AccessIpListIngress.ValueString() != state.AccessIpListIngress.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ControlPlaneSizingDisk.IsNull() != state.ControlPlaneSizingDisk.IsNull() || plan.ControlPlaneSizingDisk.IsUnknown() != state.ControlPlaneSizingDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ControlPlaneSizingDisk.IsNull() && !plan.ControlPlaneSizingDisk.IsUnknown() && !state.ControlPlaneSizingDisk.IsNull() && !state.ControlPlaneSizingDisk.IsUnknown() { - if plan.ControlPlaneSizingDisk.ValueInt64() != state.ControlPlaneSizingDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.WorkersSizingDisk.IsNull() != state.WorkersSizingDisk.IsNull() || plan.WorkersSizingDisk.IsUnknown() != state.WorkersSizingDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.WorkersSizingDisk.IsNull() && !plan.WorkersSizingDisk.IsUnknown() && !state.WorkersSizingDisk.IsNull() && !state.WorkersSizingDisk.IsUnknown() { - if plan.WorkersSizingDisk.ValueInt64() != state.WorkersSizingDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 362: resources_core.FormatInt64(plan.ControlPlaneCount), - 363: resources_core.FormatInt64(plan.WorkersCount), - 364: resources_core.FormatString(plan.AccessIpListAPI), - 365: resources_core.FormatString(plan.AccessIpListIngress), - 563: resources_core.FormatString(plan.AppVersion), - 637: resources_core.FormatInt64(plan.ControlPlaneSizingDisk), - 638: resources_core.FormatInt64(plan.WorkersSizingDisk), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 150, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpListAPI", Field: "AccessIpListAPI", Type: "string"}, - {Code: "accessIpListIngress", Field: "AccessIpListIngress", Type: "string"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "clusterName", Field: "ClusterName", Type: "string"}, - {Code: "controlPlaneCount", Field: "ControlPlaneCount", Type: "int64"}, - {Code: "controlPlaneSizingDisk", Field: "ControlPlaneSizingDisk", Type: "int64"}, - {Code: "controlPlaneSizingPolicy", Field: "ControlPlaneSizingPolicy", Type: "string"}, - {Code: "needExternalAddressAPI", Field: "NeedExternalAddressAPI", Type: "bool"}, - {Code: "needExternalAddressIngress", Field: "NeedExternalAddressIngress", Type: "bool"}, - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "workersCount", Field: "WorkersCount", Type: "int64"}, - {Code: "workersSizingDisk", Field: "WorkersSizingDisk", Type: "int64"}, - {Code: "workersSizingPolicy", Field: "WorkersSizingPolicy", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *K8sSthutrvalClusterResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *K8sSthutrvalClusterResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/150_k8s_sthutrval_cluster_update_secrets_action.go b/generated/prod/go/150_k8s_sthutrval_cluster_update_secrets_action.go deleted file mode 100644 index abb4ff8..0000000 --- a/generated/prod/go/150_k8s_sthutrval_cluster_update_secrets_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_sthutrval_cluster -// Action: update_secrets - -var _ resource.Resource = &K8sSthutrvalClusterUpdateSecretsResource{} - -// K8sSthutrvalClusterUpdateSecretsResource triggers a one-time action. -type K8sSthutrvalClusterUpdateSecretsResource struct { - client *core.UniversalClient -} - -type K8sSthutrvalClusterUpdateSecretsModel struct { - ID types.String `tfsdk:"id"` - K8sSthutrvalClusterID types.String `tfsdk:"k8s_sthutrval_cluster_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewK8sSthutrvalClusterUpdateSecretsResource() resource.Resource { - return &K8sSthutrvalClusterUpdateSecretsResource{} -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_sthutrval_cluster_update_secrets" -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "k8s_sthutrval_cluster_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sSthutrvalClusterUpdateSecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "update_secrets", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "update_secrets", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sSthutrvalClusterUpdateSecretsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sSthutrvalClusterUpdateSecretsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "update_secrets", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "update_secrets", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *K8sSthutrvalClusterUpdateSecretsResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/19_vc_org_reconcile_action.go b/generated/prod/go/19_vc_org_reconcile_action.go deleted file mode 100644 index 3e5dc0f..0000000 --- a/generated/prod/go/19_vc_org_reconcile_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_org -// Action: reconcile - -var _ resource.Resource = &VcOrgReconcileResource{} - -// VcOrgReconcileResource triggers a one-time action. -type VcOrgReconcileResource struct { - client *core.UniversalClient -} - -type VcOrgReconcileModel struct { - ID types.String `tfsdk:"id"` - VcOrgID types.String `tfsdk:"vc_org_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewVcOrgReconcileResource() resource.Resource { - return &VcOrgReconcileResource{} -} - -func (r *VcOrgReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_org_reconcile" -} - -func (r *VcOrgReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_org_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcOrgReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcOrgReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcOrgID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcOrgReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcOrgReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcOrgReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcOrgID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcOrgReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcOrgReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/19_vc_org_resource.go b/generated/prod/go/19_vc_org_resource.go deleted file mode 100644 index c070e03..0000000 --- a/generated/prod/go/19_vc_org_resource.go +++ /dev/null @@ -1,372 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_org -// Service ID: 19 - -var _ resource.Resource = &VcOrgResource{} -var _ resource.ResourceWithModifyPlan = &VcOrgResource{} -var _ resource.ResourceWithImportState = &VcOrgResource{} - -type VcOrgResource struct { - client *core.UniversalClient -} - -type VcOrgModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - OrganizationType types.String `tfsdk:"organization_type"` - ResourceRealm types.String `tfsdk:"resource_realm"` - VIPConfigure types.String `tfsdk:"v_i_p_configure"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcOrgResource() resource.Resource { - return &VcOrgResource{} -} - -func (r *VcOrgResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_org" -} - -func (r *VcOrgResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "organization_type": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("iaas"), MarkdownDescription: "Доступ к организации предоставляется только при выборе `iaas` Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Облако в котором будет развёрнут тенант Не изменяется после создания."}, - "v_i_p_configure": schema.StringAttribute{Required: true}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcOrgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcOrgModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.OrganizationType.IsNull() && !plan.OrganizationType.IsUnknown() && !state.OrganizationType.IsNull() && !state.OrganizationType.IsUnknown() { - if plan.OrganizationType.ValueString() != state.OrganizationType.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить organization_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.VIPConfigure.IsNull() || config.VIPConfigure.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "v_i_p_configure is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 418: resources_core.FormatString(config.ResourceRealm), - 556: resources_core.FormatString(config.OrganizationType), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 19, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcOrgResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.VIPConfigure.IsNull() || data.VIPConfigure.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "v_i_p_configure is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 19, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 418: resources_core.FormatString(data.ResourceRealm), - 556: resources_core.FormatString(data.OrganizationType), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 19, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 19, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 19, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcOrgResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcOrgModel - var state VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.VIPConfigure.IsNull() != state.VIPConfigure.IsNull() || plan.VIPConfigure.IsUnknown() != state.VIPConfigure.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VIPConfigure.IsNull() && !plan.VIPConfigure.IsUnknown() && !state.VIPConfigure.IsNull() && !state.VIPConfigure.IsUnknown() { - if plan.VIPConfigure.ValueString() != state.VIPConfigure.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 662: resources_core.FormatString(plan.VIPConfigure), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 19, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcOrgResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcOrgResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/1_dummy_redeploy_action.go b/generated/prod/go/1_dummy_redeploy_action.go deleted file mode 100644 index aaf8c7f..0000000 --- a/generated/prod/go/1_dummy_redeploy_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dummy -// Action: redeploy - -var _ resource.Resource = &DummyRedeployResource{} - -// DummyRedeployResource triggers a one-time action. -type DummyRedeployResource struct { - client *core.UniversalClient -} - -type DummyRedeployModel struct { - ID types.String `tfsdk:"id"` - DummyID types.String `tfsdk:"dummy_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewDummyRedeployResource() resource.Resource { - return &DummyRedeployResource{} -} - -func (r *DummyRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dummy_redeploy" -} - -func (r *DummyRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "dummy_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DummyRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan DummyRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.DummyID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *DummyRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DummyRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DummyRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.DummyID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *DummyRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *DummyRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/1_dummy_resource.go b/generated/prod/go/1_dummy_resource.go deleted file mode 100644 index 2a24798..0000000 --- a/generated/prod/go/1_dummy_resource.go +++ /dev/null @@ -1,507 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dummy -// Service ID: 1 - -var _ resource.Resource = &DummyResource{} -var _ resource.ResourceWithModifyPlan = &DummyResource{} -var _ resource.ResourceWithImportState = &DummyResource{} - -type DummyResource struct { - client *core.UniversalClient -} - -type DummyModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ArrayMapFixedExample types.String `tfsdk:"array_map_fixed_example"` - Bodymessage types.String `tfsdk:"bodymessage"` - DurationMs types.Int64 `tfsdk:"duration_ms"` - FailAtStart types.Bool `tfsdk:"fail_at_start"` - FailInProgress types.Bool `tfsdk:"fail_in_progress"` - JsonExample types.String `tfsdk:"json_example"` - MapExample types.String `tfsdk:"map_example"` - MapFixed types.String `tfsdk:"map_fixed"` - NestedRefExample types.String `tfsdk:"nested_ref_example"` - ResourceRealm types.String `tfsdk:"resource_realm"` - WhereFail types.Int64 `tfsdk:"where_fail"` - YamlExample types.String `tfsdk:"yaml_example"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDummyResource() resource.Resource { - return &DummyResource{} -} - -func (r *DummyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dummy" -} - -func (r *DummyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "array_map_fixed_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Array of map-fixed Не изменяется после создания."}, - "bodymessage": schema.StringAttribute{Optional: true, MarkdownDescription: "Дата, уходящая в Vault"}, - "duration_ms": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "перед завершением подождать (sleep) столько миллисекунд"}, - "fail_at_start": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "если true, завершить джоб, ничего не записывая в cmdb"}, - "fail_in_progress": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb"}, - "json_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Для тестирования интерфейса"}, - "map_example": schema.StringAttribute{Optional: true}, - "map_fixed": schema.StringAttribute{Optional: true, MarkdownDescription: "Новый тип поля Не изменяется после создания."}, - "nested_ref_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "where_fail": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write"}, - "yaml_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DummyResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DummyModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ArrayMapFixedExample.IsNull() && !plan.ArrayMapFixedExample.IsUnknown() && !state.ArrayMapFixedExample.IsNull() && !state.ArrayMapFixedExample.IsUnknown() { - if plan.ArrayMapFixedExample.ValueString() != state.ArrayMapFixedExample.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить array_map_fixed_example", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MapFixed.IsNull() && !plan.MapFixed.IsUnknown() && !state.MapFixed.IsNull() && !state.MapFixed.IsUnknown() { - if plan.MapFixed.ValueString() != state.MapFixed.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить map_fixed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NestedRefExample.IsNull() && !plan.NestedRefExample.IsUnknown() && !state.NestedRefExample.IsNull() && !state.NestedRefExample.IsUnknown() { - if plan.NestedRefExample.ValueString() != state.NestedRefExample.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить nested_ref_example", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.YamlExample.IsNull() && !plan.YamlExample.IsUnknown() && !state.YamlExample.IsNull() && !state.YamlExample.IsUnknown() { - if plan.YamlExample.ValueString() != state.YamlExample.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить yaml_example", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 198: resources_core.FormatInt64(config.DurationMs), - 199: resources_core.FormatBool(config.FailAtStart), - 200: resources_core.FormatBool(config.FailInProgress), - 201: resources_core.FormatInt64(config.WhereFail), - 242: resources_core.FormatString(config.ResourceRealm), - 286: resources_core.FormatString(config.Bodymessage), - 321: resources_core.FormatString(config.MapExample), - 322: resources_core.FormatString(config.JsonExample), - 396: resources_core.FormatString(config.NestedRefExample), - 447: resources_core.FormatString(config.YamlExample), - 647: resources_core.FormatString(config.MapFixed), - 654: resources_core.FormatString(config.ArrayMapFixedExample), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 1, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DummyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 1, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 198: resources_core.FormatInt64(data.DurationMs), - 199: resources_core.FormatBool(data.FailAtStart), - 200: resources_core.FormatBool(data.FailInProgress), - 201: resources_core.FormatInt64(data.WhereFail), - 242: resources_core.FormatString(data.ResourceRealm), - 286: resources_core.FormatString(data.Bodymessage), - 321: resources_core.FormatString(data.MapExample), - 322: resources_core.FormatString(data.JsonExample), - 396: resources_core.FormatString(data.NestedRefExample), - 447: resources_core.FormatString(data.YamlExample), - 647: resources_core.FormatString(data.MapFixed), - 654: resources_core.FormatString(data.ArrayMapFixedExample), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 1, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 1, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - {Code: "yamlExample", Field: "YamlExample", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 1, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - {Code: "yamlExample", Field: "YamlExample", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DummyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DummyModel - var state DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.DurationMs.IsNull() != state.DurationMs.IsNull() || plan.DurationMs.IsUnknown() != state.DurationMs.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.DurationMs.IsNull() && !plan.DurationMs.IsUnknown() && !state.DurationMs.IsNull() && !state.DurationMs.IsUnknown() { - if plan.DurationMs.ValueInt64() != state.DurationMs.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.FailAtStart.IsNull() != state.FailAtStart.IsNull() || plan.FailAtStart.IsUnknown() != state.FailAtStart.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.FailAtStart.IsNull() && !plan.FailAtStart.IsUnknown() && !state.FailAtStart.IsNull() && !state.FailAtStart.IsUnknown() { - if plan.FailAtStart.ValueBool() != state.FailAtStart.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.FailInProgress.IsNull() != state.FailInProgress.IsNull() || plan.FailInProgress.IsUnknown() != state.FailInProgress.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.FailInProgress.IsNull() && !plan.FailInProgress.IsUnknown() && !state.FailInProgress.IsNull() && !state.FailInProgress.IsUnknown() { - if plan.FailInProgress.ValueBool() != state.FailInProgress.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.WhereFail.IsNull() != state.WhereFail.IsNull() || plan.WhereFail.IsUnknown() != state.WhereFail.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.WhereFail.IsNull() && !plan.WhereFail.IsUnknown() && !state.WhereFail.IsNull() && !state.WhereFail.IsUnknown() { - if plan.WhereFail.ValueInt64() != state.WhereFail.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.Bodymessage.IsNull() != state.Bodymessage.IsNull() || plan.Bodymessage.IsUnknown() != state.Bodymessage.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.Bodymessage.IsNull() && !plan.Bodymessage.IsUnknown() && !state.Bodymessage.IsNull() && !state.Bodymessage.IsUnknown() { - if plan.Bodymessage.ValueString() != state.Bodymessage.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MapExample.IsNull() != state.MapExample.IsNull() || plan.MapExample.IsUnknown() != state.MapExample.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MapExample.IsNull() && !plan.MapExample.IsUnknown() && !state.MapExample.IsNull() && !state.MapExample.IsUnknown() { - if plan.MapExample.ValueString() != state.MapExample.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonExample.IsNull() != state.JsonExample.IsNull() || plan.JsonExample.IsUnknown() != state.JsonExample.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonExample.IsNull() && !plan.JsonExample.IsUnknown() && !state.JsonExample.IsNull() && !state.JsonExample.IsUnknown() { - if plan.JsonExample.ValueString() != state.JsonExample.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 287: resources_core.FormatInt64(plan.DurationMs), - 288: resources_core.FormatBool(plan.FailAtStart), - 289: resources_core.FormatBool(plan.FailInProgress), - 290: resources_core.FormatInt64(plan.WhereFail), - 291: resources_core.FormatString(plan.Bodymessage), - 373: resources_core.FormatString(plan.MapExample), - 374: resources_core.FormatString(plan.JsonExample), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 1, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - {Code: "yamlExample", Field: "YamlExample", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DummyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DummyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/20_vc_org_saas_resource.go b/generated/prod/go/20_vc_org_saas_resource.go deleted file mode 100644 index 7488f49..0000000 --- a/generated/prod/go/20_vc_org_saas_resource.go +++ /dev/null @@ -1,334 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_org_saas -// Service ID: 20 - -var _ resource.Resource = &VcOrgSaasResource{} -var _ resource.ResourceWithModifyPlan = &VcOrgSaasResource{} -var _ resource.ResourceWithImportState = &VcOrgSaasResource{} - -type VcOrgSaasResource struct { - client *core.UniversalClient -} - -type VcOrgSaasModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcOrgSaasResource() resource.Resource { - return &VcOrgSaasResource{} -} - -func (r *VcOrgSaasResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_org_saas" -} - -func (r *VcOrgSaasResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcOrgSaasResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcOrgSaasModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcOrgSaasModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcOrgSaasModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 185: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 20, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcOrgSaasResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcOrgSaasModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 20, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 185: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 20, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 20, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgSaasResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcOrgSaasModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 20, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcOrgSaasResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcOrgSaasModel - var state VcOrgSaasModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 20, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgSaasResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcOrgSaasModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcOrgSaasResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcOrgSaasResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/21_vc_vdc_reconcile_action.go b/generated/prod/go/21_vc_vdc_reconcile_action.go deleted file mode 100644 index 691819f..0000000 --- a/generated/prod/go/21_vc_vdc_reconcile_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc -// Action: reconcile - -var _ resource.Resource = &VcVdcReconcileResource{} - -// VcVdcReconcileResource triggers a one-time action. -type VcVdcReconcileResource struct { - client *core.UniversalClient -} - -type VcVdcReconcileModel struct { - ID types.String `tfsdk:"id"` - VcVdcID types.String `tfsdk:"vc_vdc_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewVcVdcReconcileResource() resource.Resource { - return &VcVdcReconcileResource{} -} - -func (r *VcVdcReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_reconcile" -} - -func (r *VcVdcReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vdc_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVdcReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/21_vc_vdc_resource.go b/generated/prod/go/21_vc_vdc_resource.go deleted file mode 100644 index 5838894..0000000 --- a/generated/prod/go/21_vc_vdc_resource.go +++ /dev/null @@ -1,521 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc -// Service ID: 21 - -var _ resource.Resource = &VcVdcResource{} -var _ resource.ResourceWithModifyPlan = &VcVdcResource{} -var _ resource.ResourceWithImportState = &VcVdcResource{} - -type VcVdcResource struct { - client *core.UniversalClient -} - -type VcVdcModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - CpuAllocated types.Int64 `tfsdk:"cpu_allocated"` - CpuGuaranteed types.Int64 `tfsdk:"cpu_guaranteed"` - MemAllocated types.Int64 `tfsdk:"mem_allocated"` - MemGuaranteed types.Int64 `tfsdk:"mem_guaranteed"` - NetworkProvider types.String `tfsdk:"network_provider"` - OrganizationUid types.String `tfsdk:"organization_uid"` - ProviderVdc types.String `tfsdk:"provider_vdc"` - StorageConfig types.String `tfsdk:"storage_config"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVdcResource() resource.Resource { - return &VcVdcResource{} -} - -func (r *VcVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc" -} - -func (r *VcVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "cpu_allocated": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "шт"}, - "cpu_guaranteed": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "% резервирования Не изменяется после создания."}, - "mem_allocated": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "gb"}, - "mem_guaranteed": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "% резервирования Не изменяется после создания."}, - "network_provider": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "organization_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` Не изменяется после создания."}, - "provider_vdc": schema.StringAttribute{Required: true, MarkdownDescription: "Приписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
Не изменяется после создания."}, - "storage_config": schema.StringAttribute{Required: true, MarkdownDescription: "Первая политика в списке указывается как "По умолчанию""}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVdcModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.OrganizationUid.IsNull() && !plan.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, plan.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != plan.OrganizationUid.ValueString() { - plan.OrganizationUid = types.StringValue(resolvedOrganizationUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.CpuGuaranteed.IsNull() && !plan.CpuGuaranteed.IsUnknown() && !state.CpuGuaranteed.IsNull() && !state.CpuGuaranteed.IsUnknown() { - if plan.CpuGuaranteed.ValueInt64() != state.CpuGuaranteed.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить cpu_guaranteed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MemGuaranteed.IsNull() && !plan.MemGuaranteed.IsUnknown() && !state.MemGuaranteed.IsNull() && !state.MemGuaranteed.IsUnknown() { - if plan.MemGuaranteed.ValueInt64() != state.MemGuaranteed.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить mem_guaranteed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NetworkProvider.IsNull() && !plan.NetworkProvider.IsUnknown() && !state.NetworkProvider.IsNull() && !state.NetworkProvider.IsUnknown() { - if plan.NetworkProvider.ValueString() != state.NetworkProvider.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить network_provider", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.OrganizationUid.IsNull() && !plan.OrganizationUid.IsUnknown() && !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - if plan.OrganizationUid.ValueString() != state.OrganizationUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить organization_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ProviderVdc.IsNull() && !plan.ProviderVdc.IsUnknown() && !state.ProviderVdc.IsNull() && !state.ProviderVdc.IsUnknown() { - if plan.ProviderVdc.ValueString() != state.ProviderVdc.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить provider_vdc", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.NetworkProvider.IsNull() || config.NetworkProvider.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "network_provider is required.") - return - } - if config.OrganizationUid.IsNull() || config.OrganizationUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "organization_uid is required.") - return - } - if config.ProviderVdc.IsNull() || config.ProviderVdc.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "provider_vdc is required.") - return - } - if config.StorageConfig.IsNull() || config.StorageConfig.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "storage_config is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.OrganizationUid.IsNull() && !config.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, config.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != config.OrganizationUid.ValueString() { - config.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - params := map[int]string{ - 30: resources_core.FormatString(config.OrganizationUid), - 335: resources_core.FormatString(config.ProviderVdc), - 361: resources_core.FormatString(config.StorageConfig), - 397: resources_core.FormatInt64(config.CpuGuaranteed), - 398: resources_core.FormatInt64(config.MemGuaranteed), - 557: resources_core.FormatInt64(config.CpuAllocated), - 558: resources_core.FormatInt64(config.MemAllocated), - 746: resources_core.FormatString(config.NetworkProvider), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 21, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.NetworkProvider.IsNull() || data.NetworkProvider.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "network_provider is required.") - return - } - if data.OrganizationUid.IsNull() || data.OrganizationUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "organization_uid is required.") - return - } - if data.ProviderVdc.IsNull() || data.ProviderVdc.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "provider_vdc is required.") - return - } - if data.StorageConfig.IsNull() || data.StorageConfig.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "storage_config is required.") - return - } - if !data.OrganizationUid.IsNull() && !data.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, data.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedOrganizationUid != "" && resolvedOrganizationUid != data.OrganizationUid.ValueString() { - data.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 21, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 30: resources_core.FormatString(data.OrganizationUid), - 335: resources_core.FormatString(data.ProviderVdc), - 361: resources_core.FormatString(data.StorageConfig), - 397: resources_core.FormatInt64(data.CpuGuaranteed), - 398: resources_core.FormatInt64(data.MemGuaranteed), - 557: resources_core.FormatInt64(data.CpuAllocated), - 558: resources_core.FormatInt64(data.MemAllocated), - 746: resources_core.FormatString(data.NetworkProvider), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 21, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 21, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, state.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != state.OrganizationUid.ValueString() { - state.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 21, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.OrganizationUid.IsNull() && !newState.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, newState.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != newState.OrganizationUid.ValueString() { - newState.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcModel - var state VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.CpuAllocated.IsNull() != state.CpuAllocated.IsNull() || plan.CpuAllocated.IsUnknown() != state.CpuAllocated.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.CpuAllocated.IsNull() && !plan.CpuAllocated.IsUnknown() && !state.CpuAllocated.IsNull() && !state.CpuAllocated.IsUnknown() { - if plan.CpuAllocated.ValueInt64() != state.CpuAllocated.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MemAllocated.IsNull() != state.MemAllocated.IsNull() || plan.MemAllocated.IsUnknown() != state.MemAllocated.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MemAllocated.IsNull() && !plan.MemAllocated.IsUnknown() && !state.MemAllocated.IsNull() && !state.MemAllocated.IsUnknown() { - if plan.MemAllocated.ValueInt64() != state.MemAllocated.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.StorageConfig.IsNull() != state.StorageConfig.IsNull() || plan.StorageConfig.IsUnknown() != state.StorageConfig.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.StorageConfig.IsNull() && !plan.StorageConfig.IsUnknown() && !state.StorageConfig.IsNull() && !state.StorageConfig.IsUnknown() { - if plan.StorageConfig.ValueString() != state.StorageConfig.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 560: resources_core.FormatInt64(plan.CpuAllocated), - 561: resources_core.FormatInt64(plan.MemAllocated), - 562: resources_core.FormatString(plan.StorageConfig), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 21, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, state.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != state.OrganizationUid.ValueString() { - state.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVdcResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVdcResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/22_vc_nsxt_reconcile_action.go b/generated/prod/go/22_vc_nsxt_reconcile_action.go deleted file mode 100644 index f9ed455..0000000 --- a/generated/prod/go/22_vc_nsxt_reconcile_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_nsxt -// Action: reconcile - -var _ resource.Resource = &VcNsxtReconcileResource{} - -// VcNsxtReconcileResource triggers a one-time action. -type VcNsxtReconcileResource struct { - client *core.UniversalClient -} - -type VcNsxtReconcileModel struct { - ID types.String `tfsdk:"id"` - VcNsxtID types.String `tfsdk:"vc_nsxt_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewVcNsxtReconcileResource() resource.Resource { - return &VcNsxtReconcileResource{} -} - -func (r *VcNsxtReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_nsxt_reconcile" -} - -func (r *VcNsxtReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_nsxt_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcNsxtReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcNsxtReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcNsxtID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcNsxtReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcNsxtReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcNsxtReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcNsxtReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcNsxtID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcNsxtReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcNsxtReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/22_vc_nsxt_resource.go b/generated/prod/go/22_vc_nsxt_resource.go deleted file mode 100644 index 8580ab1..0000000 --- a/generated/prod/go/22_vc_nsxt_resource.go +++ /dev/null @@ -1,525 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_nsxt -// Service ID: 22 - -var _ resource.Resource = &VcNsxtResource{} -var _ resource.ResourceWithModifyPlan = &VcNsxtResource{} -var _ resource.ResourceWithImportState = &VcNsxtResource{} - -type VcNsxtResource struct { - client *core.UniversalClient -} - -type VcNsxtModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - NeedEnableAVI types.Bool `tfsdk:"need_enable_a_v_i"` - NeedExternalAddressSNAT types.Bool `tfsdk:"need_external_address_s_n_a_t"` - VdcGroupUid types.String `tfsdk:"vdc_group_uid"` - VdcType types.String `tfsdk:"vdc_type"` - VdcUid types.String `tfsdk:"vdc_uid"` - VirtualServicesCount types.Int64 `tfsdk:"virtual_services_count"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcNsxtResource() resource.Resource { - return &VcNsxtResource{} -} - -func (r *VcNsxtResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_nsxt" -} - -func (r *VcNsxtResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "ip_space_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ip Space для внешнего IP

getKeyListFromStruct(getInstanceState(getValueFromStruct(getInstanceState(getValueFromStruct(getInstanceState(), "params.vdcUid")), "params.organizationUid")), "params.vIPConfigure")"}, - "need_enable_a_v_i": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включение Load Balancer"}, - "need_external_address_s_n_a_t": schema.BoolAttribute{Optional: true, MarkdownDescription: "Создать правило SNAT на подсеть `10.10.102.0/24`"}, - "vdc_group_uid": schema.StringAttribute{Optional: true, MarkdownDescription: "UUID Услуги `Группа виртуальных датацентров (groupvDC)` Не изменяется после создания."}, - "vdc_type": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("vdc"), MarkdownDescription: "Тип родительской услуги Не изменяется после создания."}, - "vdc_uid": schema.StringAttribute{Optional: true, MarkdownDescription: "UUID Услуги `Виртуальный датацентр (vDC)` Не изменяется после создания."}, - "virtual_services_count": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Кол-во виртуальных сервисов, которые выделяются на AVI"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcNsxtResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcNsxtModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.VdcGroupUid.IsNull() && !plan.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, plan.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != plan.VdcGroupUid.ValueString() { - plan.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - planChanged = true - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() { - plan.VdcUid = types.StringValue(resolvedVdcUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.VdcGroupUid.IsNull() && !plan.VdcGroupUid.IsUnknown() && !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - if plan.VdcGroupUid.ValueString() != state.VdcGroupUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_group_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcType.IsNull() && !plan.VdcType.IsUnknown() && !state.VdcType.IsNull() && !state.VdcType.IsUnknown() { - if plan.VdcType.ValueString() != state.VdcType.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if plan.VdcUid.ValueString() != state.VdcUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VdcGroupUid.IsNull() && !config.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, config.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != config.VdcGroupUid.ValueString() { - config.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 8: resources_core.FormatString(config.VdcUid), - 340: resources_core.FormatBool(config.NeedEnableAVI), - 341: resources_core.FormatInt64(config.VirtualServicesCount), - 621: resources_core.FormatString(config.VdcType), - 622: resources_core.FormatString(config.VdcGroupUid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 22, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcNsxtResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if !data.VdcGroupUid.IsNull() && !data.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, data.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != data.VdcGroupUid.ValueString() { - data.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 22, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 8: resources_core.FormatString(data.VdcUid), - 340: resources_core.FormatBool(data.NeedEnableAVI), - 341: resources_core.FormatInt64(data.VirtualServicesCount), - 621: resources_core.FormatString(data.VdcType), - 622: resources_core.FormatString(data.VdcGroupUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 22, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 22, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, state.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != state.VdcGroupUid.ValueString() { - state.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcNsxtResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 22, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VdcGroupUid.IsNull() && !newState.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, newState.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != newState.VdcGroupUid.ValueString() { - newState.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcNsxtResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcNsxtModel - var state VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.NeedEnableAVI.IsNull() != state.NeedEnableAVI.IsNull() || plan.NeedEnableAVI.IsUnknown() != state.NeedEnableAVI.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedEnableAVI.IsNull() && !plan.NeedEnableAVI.IsUnknown() && !state.NeedEnableAVI.IsNull() && !state.NeedEnableAVI.IsUnknown() { - if plan.NeedEnableAVI.ValueBool() != state.NeedEnableAVI.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VirtualServicesCount.IsNull() != state.VirtualServicesCount.IsNull() || plan.VirtualServicesCount.IsUnknown() != state.VirtualServicesCount.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VirtualServicesCount.IsNull() && !plan.VirtualServicesCount.IsUnknown() && !state.VirtualServicesCount.IsNull() && !state.VirtualServicesCount.IsUnknown() { - if plan.VirtualServicesCount.ValueInt64() != state.VirtualServicesCount.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressSNAT.IsNull() != state.NeedExternalAddressSNAT.IsNull() || plan.NeedExternalAddressSNAT.IsUnknown() != state.NeedExternalAddressSNAT.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressSNAT.IsNull() && !plan.NeedExternalAddressSNAT.IsUnknown() && !state.NeedExternalAddressSNAT.IsNull() && !state.NeedExternalAddressSNAT.IsUnknown() { - if plan.NeedExternalAddressSNAT.ValueBool() != state.NeedExternalAddressSNAT.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 368: resources_core.FormatBool(plan.NeedEnableAVI), - 369: resources_core.FormatInt64(plan.VirtualServicesCount), - 371: resources_core.FormatBool(plan.NeedExternalAddressSNAT), - 372: resources_core.FormatString(plan.IpSpaceName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 22, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, state.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != state.VdcGroupUid.ValueString() { - state.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcNsxtResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcNsxtResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcNsxtResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/23_vc_vm_resource.go b/generated/prod/go/23_vc_vm_resource.go deleted file mode 100644 index c891163..0000000 --- a/generated/prod/go/23_vc_vm_resource.go +++ /dev/null @@ -1,509 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm -// Service ID: 23 - -var _ resource.Resource = &VcVmResource{} -var _ resource.ResourceWithModifyPlan = &VcVmResource{} -var _ resource.ResourceWithImportState = &VcVmResource{} - -type VcVmResource struct { - client *core.UniversalClient -} - -type VcVmModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AccessIpList types.String `tfsdk:"access_ip_list"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - TemplateName types.String `tfsdk:"template_name"` - VappUid types.String `tfsdk:"vapp_uid"` - VmCpu types.String `tfsdk:"vm_cpu"` - VmDisksize types.String `tfsdk:"vm_disksize"` - VmName types.String `tfsdk:"vm_name"` - VmRam types.String `tfsdk:"vm_ram"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVmResource() resource.Resource { - return &VcVmResource{} -} - -func (r *VcVmResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm" -} - -func (r *VcVmResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "access_ip_list": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("79.111.119.78/32 185.247.187.1/32"), MarkdownDescription: "Вставить содержимое из 'curl ifconfig.io'
IP адреса в CIDR формате через пробел для настройки аксес листов"}, - "ip_space_name": schema.StringAttribute{Required: true, MarkdownDescription: "Брать из свойств ресурсной платформы
.vcd.ipSpace

Имя IP-space для выделения внешнего IP (IP выделяется обязательно) Не изменяется после создания."}, - "template_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("RockyLinux_9-16G"), MarkdownDescription: "ОС Не изменяется после создания."}, - "vapp_uid": schema.StringAttribute{Required: true, MarkdownDescription: "InstanceUid vApp. vApp должен быть создан Не изменяется после создания."}, - "vm_cpu": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("2"), MarkdownDescription: "CPU"}, - "vm_disksize": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("10"), MarkdownDescription: "Размер диска под сервис (GB)"}, - "vm_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("vm0001"), MarkdownDescription: "Имя ВМ. Не поддерживает спец-символы Не изменяется после создания."}, - "vm_ram": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("2"), MarkdownDescription: "RAM (GB)"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVmModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVmModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVmModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, plan.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != plan.VappUid.ValueString() { - plan.VappUid = types.StringValue(resolvedVappUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.TemplateName.IsNull() && !plan.TemplateName.IsUnknown() && !state.TemplateName.IsNull() && !state.TemplateName.IsUnknown() { - if plan.TemplateName.ValueString() != state.TemplateName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить template_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - if plan.VappUid.ValueString() != state.VappUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vapp_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VmName.IsNull() && !plan.VmName.IsUnknown() && !state.VmName.IsNull() && !state.VmName.IsUnknown() { - if plan.VmName.ValueString() != state.VmName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vm_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.IpSpaceName.IsNull() || config.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if config.VappUid.IsNull() || config.VappUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VappUid.IsNull() && !config.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, config.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != config.VappUid.ValueString() { - config.VappUid = types.StringValue(resolvedVappUid) - } - } - params := map[int]string{ - 33: resources_core.FormatString(config.VappUid), - 35: resources_core.FormatString(config.VmName), - 36: resources_core.FormatString(config.VmCpu), - 37: resources_core.FormatString(config.VmRam), - 38: resources_core.FormatString(config.VmDisksize), - 176: resources_core.FormatString(config.TemplateName), - 177: resources_core.FormatString(config.AccessIpList), - 406: resources_core.FormatString(config.IpSpaceName), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 23, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVmResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVmModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if data.VappUid.IsNull() || data.VappUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - if !data.VappUid.IsNull() && !data.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, data.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVappUid != "" && resolvedVappUid != data.VappUid.ValueString() { - data.VappUid = types.StringValue(resolvedVappUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 23, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 33: resources_core.FormatString(data.VappUid), - 35: resources_core.FormatString(data.VmName), - 36: resources_core.FormatString(data.VmCpu), - 37: resources_core.FormatString(data.VmRam), - 38: resources_core.FormatString(data.VmDisksize), - 176: resources_core.FormatString(data.TemplateName), - 177: resources_core.FormatString(data.AccessIpList), - 406: resources_core.FormatString(data.IpSpaceName), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 23, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 23, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "templateName", Field: "TemplateName", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "string"}, - {Code: "vmDisksize", Field: "VmDisksize", Type: "string"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 23, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "templateName", Field: "TemplateName", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "string"}, - {Code: "vmDisksize", Field: "VmDisksize", Type: "string"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VappUid.IsNull() && !newState.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, newState.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != newState.VappUid.ValueString() { - newState.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVmResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmModel - var state VcVmModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.VmCpu.IsNull() != state.VmCpu.IsNull() || plan.VmCpu.IsUnknown() != state.VmCpu.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmCpu.IsNull() && !plan.VmCpu.IsUnknown() && !state.VmCpu.IsNull() && !state.VmCpu.IsUnknown() { - if plan.VmCpu.ValueString() != state.VmCpu.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmRam.IsNull() != state.VmRam.IsNull() || plan.VmRam.IsUnknown() != state.VmRam.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmRam.IsNull() && !plan.VmRam.IsUnknown() && !state.VmRam.IsNull() && !state.VmRam.IsUnknown() { - if plan.VmRam.ValueString() != state.VmRam.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmDisksize.IsNull() != state.VmDisksize.IsNull() || plan.VmDisksize.IsUnknown() != state.VmDisksize.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmDisksize.IsNull() && !plan.VmDisksize.IsUnknown() && !state.VmDisksize.IsNull() && !state.VmDisksize.IsUnknown() { - if plan.VmDisksize.ValueString() != state.VmDisksize.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessIpList.IsNull() != state.AccessIpList.IsNull() || plan.AccessIpList.IsUnknown() != state.AccessIpList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessIpList.IsNull() && !plan.AccessIpList.IsUnknown() && !state.AccessIpList.IsNull() && !state.AccessIpList.IsUnknown() { - if plan.AccessIpList.ValueString() != state.AccessIpList.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 186: resources_core.FormatString(plan.VmCpu), - 187: resources_core.FormatString(plan.VmRam), - 188: resources_core.FormatString(plan.VmDisksize), - 189: resources_core.FormatString(plan.AccessIpList), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 23, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "templateName", Field: "TemplateName", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "string"}, - {Code: "vmDisksize", Field: "VmDisksize", Type: "string"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVmModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVmResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVmResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/25_vcexternalip_resource.go b/generated/prod/go/25_vcexternalip_resource.go deleted file mode 100644 index 5f89219..0000000 --- a/generated/prod/go/25_vcexternalip_resource.go +++ /dev/null @@ -1,558 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vcexternalip -// Service ID: 25 - -var _ resource.Resource = &VcexternalipResource{} -var _ resource.ResourceWithModifyPlan = &VcexternalipResource{} -var _ resource.ResourceWithImportState = &VcexternalipResource{} - -type VcexternalipResource struct { - client *core.UniversalClient -} - -type VcexternalipModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - DnatCreate types.Bool `tfsdk:"dnat_create"` - FromServiceCloudEdgeName types.String `tfsdk:"from_service_cloud_edge_name"` - FromServiceCloudEdgeScope types.String `tfsdk:"from_service_cloud_edge_scope"` - FromServiceCloudOrgName types.String `tfsdk:"from_service_cloud_org_name"` - FromServiceCloudVdcName types.String `tfsdk:"from_service_cloud_vdc_name"` - FromServiceCloudVmwareUrl types.String `tfsdk:"from_service_cloud_vmware_url"` - FromServiceNamespace types.String `tfsdk:"from_service_namespace"` - FromServiceVdcGroupName types.String `tfsdk:"from_service_vdc_group_name"` - InternalAddrAccess types.String `tfsdk:"internal_addr_access"` - InternalPortAccess types.String `tfsdk:"internal_port_access"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - ResourceRealm types.String `tfsdk:"resource_realm"` - ServiceUid types.String `tfsdk:"service_uid"` - SnatCreate types.Bool `tfsdk:"snat_create"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcexternalipResource() resource.Resource { - return &VcexternalipResource{} -} - -func (r *VcexternalipResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vcexternalip" -} - -func (r *VcexternalipResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "dnat_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Необходимо создать DNAT-правило."}, - "from_service_cloud_edge_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Edge составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_edge_scope": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "from_service_cloud_org_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Org составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_vdc_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Vdc составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_vmware_url": schema.StringAttribute{Optional: true, MarkdownDescription: "Api-Url составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_namespace": schema.StringAttribute{Required: true, MarkdownDescription: "Namespace составной услуги (для отображения правил FW) Не изменяется после создания."}, - "from_service_vdc_group_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "internal_addr_access": schema.StringAttribute{Required: true, MarkdownDescription: "Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true"}, - "internal_port_access": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("5432"), MarkdownDescription: "Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
"}, - "ip_space_name": schema.StringAttribute{Required: true, MarkdownDescription: "Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "service_uid": schema.StringAttribute{Required: true}, - "snat_create": schema.BoolAttribute{Optional: true, MarkdownDescription: "Необходимо создать SNAT-правило.
"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcexternalipResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcexternalipModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.FromServiceCloudEdgeName.IsNull() && !plan.FromServiceCloudEdgeName.IsUnknown() && !state.FromServiceCloudEdgeName.IsNull() && !state.FromServiceCloudEdgeName.IsUnknown() { - if plan.FromServiceCloudEdgeName.ValueString() != state.FromServiceCloudEdgeName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_edge_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudEdgeScope.IsNull() && !plan.FromServiceCloudEdgeScope.IsUnknown() && !state.FromServiceCloudEdgeScope.IsNull() && !state.FromServiceCloudEdgeScope.IsUnknown() { - if plan.FromServiceCloudEdgeScope.ValueString() != state.FromServiceCloudEdgeScope.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_edge_scope", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudOrgName.IsNull() && !plan.FromServiceCloudOrgName.IsUnknown() && !state.FromServiceCloudOrgName.IsNull() && !state.FromServiceCloudOrgName.IsUnknown() { - if plan.FromServiceCloudOrgName.ValueString() != state.FromServiceCloudOrgName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_org_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudVdcName.IsNull() && !plan.FromServiceCloudVdcName.IsUnknown() && !state.FromServiceCloudVdcName.IsNull() && !state.FromServiceCloudVdcName.IsUnknown() { - if plan.FromServiceCloudVdcName.ValueString() != state.FromServiceCloudVdcName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_vdc_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudVmwareUrl.IsNull() && !plan.FromServiceCloudVmwareUrl.IsUnknown() && !state.FromServiceCloudVmwareUrl.IsNull() && !state.FromServiceCloudVmwareUrl.IsUnknown() { - if plan.FromServiceCloudVmwareUrl.ValueString() != state.FromServiceCloudVmwareUrl.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_vmware_url", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceNamespace.IsNull() && !plan.FromServiceNamespace.IsUnknown() && !state.FromServiceNamespace.IsNull() && !state.FromServiceNamespace.IsUnknown() { - if plan.FromServiceNamespace.ValueString() != state.FromServiceNamespace.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_namespace", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceVdcGroupName.IsNull() && !plan.FromServiceVdcGroupName.IsUnknown() && !state.FromServiceVdcGroupName.IsNull() && !state.FromServiceVdcGroupName.IsUnknown() { - if plan.FromServiceVdcGroupName.ValueString() != state.FromServiceVdcGroupName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить from_service_vdc_group_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.FromServiceNamespace.IsNull() || config.FromServiceNamespace.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "from_service_namespace is required.") - return - } - if config.InternalAddrAccess.IsNull() || config.InternalAddrAccess.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "internal_addr_access is required.") - return - } - if config.IpSpaceName.IsNull() || config.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ServiceUid.IsNull() || config.ServiceUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "service_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 140: resources_core.FormatString(config.ServiceUid), - 141: resources_core.FormatBool(config.DnatCreate), - 142: resources_core.FormatString(config.InternalPortAccess), - 143: resources_core.FormatBool(config.SnatCreate), - 144: resources_core.FormatString(config.InternalAddrAccess), - 324: resources_core.FormatString(config.FromServiceNamespace), - 325: resources_core.FormatString(config.FromServiceCloudEdgeName), - 326: resources_core.FormatString(config.FromServiceCloudVdcName), - 327: resources_core.FormatString(config.FromServiceCloudOrgName), - 328: resources_core.FormatString(config.FromServiceCloudVmwareUrl), - 336: resources_core.FormatString(config.IpSpaceName), - 488: resources_core.FormatString(config.ResourceRealm), - 624: resources_core.FormatString(config.FromServiceCloudEdgeScope), - 626: resources_core.FormatString(config.FromServiceVdcGroupName), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 25, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcexternalipResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.FromServiceNamespace.IsNull() || data.FromServiceNamespace.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "from_service_namespace is required.") - return - } - if data.InternalAddrAccess.IsNull() || data.InternalAddrAccess.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "internal_addr_access is required.") - return - } - if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.ServiceUid.IsNull() || data.ServiceUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "service_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 25, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 140: resources_core.FormatString(data.ServiceUid), - 141: resources_core.FormatBool(data.DnatCreate), - 142: resources_core.FormatString(data.InternalPortAccess), - 143: resources_core.FormatBool(data.SnatCreate), - 144: resources_core.FormatString(data.InternalAddrAccess), - 324: resources_core.FormatString(data.FromServiceNamespace), - 325: resources_core.FormatString(data.FromServiceCloudEdgeName), - 326: resources_core.FormatString(data.FromServiceCloudVdcName), - 327: resources_core.FormatString(data.FromServiceCloudOrgName), - 328: resources_core.FormatString(data.FromServiceCloudVmwareUrl), - 336: resources_core.FormatString(data.IpSpaceName), - 488: resources_core.FormatString(data.ResourceRealm), - 624: resources_core.FormatString(data.FromServiceCloudEdgeScope), - 626: resources_core.FormatString(data.FromServiceVdcGroupName), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 25, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 25, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcexternalipResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 25, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcexternalipResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcexternalipModel - var state VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ServiceUid.IsNull() != state.ServiceUid.IsNull() || plan.ServiceUid.IsUnknown() != state.ServiceUid.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ServiceUid.IsNull() && !plan.ServiceUid.IsUnknown() && !state.ServiceUid.IsNull() && !state.ServiceUid.IsUnknown() { - if plan.ServiceUid.ValueString() != state.ServiceUid.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.DnatCreate.IsNull() != state.DnatCreate.IsNull() || plan.DnatCreate.IsUnknown() != state.DnatCreate.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.DnatCreate.IsNull() && !plan.DnatCreate.IsUnknown() && !state.DnatCreate.IsNull() && !state.DnatCreate.IsUnknown() { - if plan.DnatCreate.ValueBool() != state.DnatCreate.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.SnatCreate.IsNull() != state.SnatCreate.IsNull() || plan.SnatCreate.IsUnknown() != state.SnatCreate.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.SnatCreate.IsNull() && !plan.SnatCreate.IsUnknown() && !state.SnatCreate.IsNull() && !state.SnatCreate.IsUnknown() { - if plan.SnatCreate.ValueBool() != state.SnatCreate.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.InternalPortAccess.IsNull() != state.InternalPortAccess.IsNull() || plan.InternalPortAccess.IsUnknown() != state.InternalPortAccess.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.InternalPortAccess.IsNull() && !plan.InternalPortAccess.IsUnknown() && !state.InternalPortAccess.IsNull() && !state.InternalPortAccess.IsUnknown() { - if plan.InternalPortAccess.ValueString() != state.InternalPortAccess.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.InternalAddrAccess.IsNull() != state.InternalAddrAccess.IsNull() || plan.InternalAddrAccess.IsUnknown() != state.InternalAddrAccess.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.InternalAddrAccess.IsNull() && !plan.InternalAddrAccess.IsUnknown() && !state.InternalAddrAccess.IsNull() && !state.InternalAddrAccess.IsUnknown() { - if plan.InternalAddrAccess.ValueString() != state.InternalAddrAccess.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 627: resources_core.FormatString(plan.ServiceUid), - 628: resources_core.FormatString(plan.IpSpaceName), - 629: resources_core.FormatBool(plan.DnatCreate), - 630: resources_core.FormatBool(plan.SnatCreate), - 631: resources_core.FormatString(plan.InternalPortAccess), - 632: resources_core.FormatString(plan.InternalAddrAccess), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 25, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcexternalipResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcexternalipResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcexternalipResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/26_vapp_resource.go b/generated/prod/go/26_vapp_resource.go deleted file mode 100644 index 8d4b291..0000000 --- a/generated/prod/go/26_vapp_resource.go +++ /dev/null @@ -1,485 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vapp -// Service ID: 26 - -var _ resource.Resource = &VappResource{} -var _ resource.ResourceWithModifyPlan = &VappResource{} -var _ resource.ResourceWithImportState = &VappResource{} - -type VappResource struct { - client *core.UniversalClient -} - -type VappModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - NsxtUid types.String `tfsdk:"nsxt_uid"` - VappName types.String `tfsdk:"vapp_name"` - VdcUid types.String `tfsdk:"vdc_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVappResource() resource.Resource { - return &VappResource{} -} - -func (r *VappResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vapp" -} - -func (r *VappResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "nsxt_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги `Сетевой шлюз периметра (Edge)` Не изменяется после создания."}, - "vapp_name": schema.StringAttribute{Required: true, MarkdownDescription: "Уникальное в рамках организации Не изменяется после создания."}, - "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги `Виртуальный датацентр (vDC)` Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VappResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VappModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, plan.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != plan.NsxtUid.ValueString() { - plan.NsxtUid = types.StringValue(resolvedNsxtUid) - planChanged = true - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() { - plan.VdcUid = types.StringValue(resolvedVdcUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - if plan.NsxtUid.ValueString() != state.NsxtUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить nsxt_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappName.IsNull() && !plan.VappName.IsUnknown() && !state.VappName.IsNull() && !state.VappName.IsUnknown() { - if plan.VappName.ValueString() != state.VappName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vapp_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if plan.VdcUid.ValueString() != state.VdcUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.NsxtUid.IsNull() || config.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if config.VappName.IsNull() || config.VappName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.NsxtUid.IsNull() && !config.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, config.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != config.NsxtUid.ValueString() { - config.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 190: resources_core.FormatString(config.NsxtUid), - 191: resources_core.FormatString(config.VappName), - 623: resources_core.FormatString(config.VdcUid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 26, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VappResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.NsxtUid.IsNull() || data.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if data.VappName.IsNull() || data.VappName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if !data.NsxtUid.IsNull() && !data.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, data.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedNsxtUid != "" && resolvedNsxtUid != data.NsxtUid.ValueString() { - data.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 26, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 190: resources_core.FormatString(data.NsxtUid), - 191: resources_core.FormatString(data.VappName), - 623: resources_core.FormatString(data.VdcUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 26, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 26, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VappResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 26, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.NsxtUid.IsNull() && !newState.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, newState.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != newState.NsxtUid.ValueString() { - newState.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VappResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VappModel - var state VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 26, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VappResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VappResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VappResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/27_vc_vm_v2_resource.go b/generated/prod/go/27_vc_vm_v2_resource.go deleted file mode 100644 index 1253004..0000000 --- a/generated/prod/go/27_vc_vm_v2_resource.go +++ /dev/null @@ -1,332 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm_v2 -// Service ID: 27 - -var _ resource.Resource = &VcVmV2Resource{} -var _ resource.ResourceWithModifyPlan = &VcVmV2Resource{} -var _ resource.ResourceWithImportState = &VcVmV2Resource{} - -type VcVmV2Resource struct { - client *core.UniversalClient -} - -type VcVmV2Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ServerListJson types.String `tfsdk:"server_list_json"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVmV2Resource() resource.Resource { - return &VcVmV2Resource{} -} - -func (r *VcVmV2Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm_v2" -} - -func (r *VcVmV2Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "server_list_json": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Необходимо изменить vappUid и ipSpaceName
Пример конфигурации взять по ссылке ниже

Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2)"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmV2Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVmV2Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVmV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVmV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 301: resources_core.FormatString(config.ServerListJson), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 27, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVmV2Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVmV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 27, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 301: resources_core.FormatString(data.ServerListJson), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 27, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 27, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "serverListJson", Field: "ServerListJson", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV2Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 27, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "serverListJson", Field: "ServerListJson", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVmV2Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmV2Model - var state VcVmV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ServerListJson.IsNull() != state.ServerListJson.IsNull() || plan.ServerListJson.IsUnknown() != state.ServerListJson.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ServerListJson.IsNull() && !plan.ServerListJson.IsUnknown() && !state.ServerListJson.IsNull() && !state.ServerListJson.IsUnknown() { - if plan.ServerListJson.ValueString() != state.ServerListJson.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 302: resources_core.FormatString(plan.ServerListJson), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 27, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "serverListJson", Field: "ServerListJson", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV2Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVmV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVmV2Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVmV2Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/28_vc_vm_v3_redeploy_action.go b/generated/prod/go/28_vc_vm_v3_redeploy_action.go deleted file mode 100644 index cd95950..0000000 --- a/generated/prod/go/28_vc_vm_v3_redeploy_action.go +++ /dev/null @@ -1,201 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm_v3 -// Action: redeploy - -var _ resource.Resource = &VcVmV3RedeployResource{} - -// VcVmV3RedeployResource triggers a one-time action. -type VcVmV3RedeployResource struct { - client *core.UniversalClient -} - -type VcVmV3RedeployModel struct { - ID types.String `tfsdk:"id"` - VcVmV3ID types.String `tfsdk:"vc_vm_v3_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - VmName types.String `tfsdk:"vm_name"` - VmCpu types.Int64 `tfsdk:"vm_cpu"` - VmRam types.Int64 `tfsdk:"vm_ram"` - VmDisk types.Int64 `tfsdk:"vm_disk"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - AccessIpList types.String `tfsdk:"access_ip_list"` - ImageVm types.String `tfsdk:"image_vm"` - UserLogin types.String `tfsdk:"user_login"` - UserPublicKey types.String `tfsdk:"user_public_key"` - CloudInit types.String `tfsdk:"cloud_init"` - AccessPortList types.String `tfsdk:"access_port_list"` -} - -func NewVcVmV3RedeployResource() resource.Resource { - return &VcVmV3RedeployResource{} -} - -func (r *VcVmV3RedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm_v3_redeploy" -} - -func (r *VcVmV3RedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vm_v3_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "vm_name": schema.StringAttribute{Required: true}, - "vm_cpu": schema.Int64Attribute{Required: true, MarkdownDescription: "шт"}, - "vm_ram": schema.Int64Attribute{Required: true, MarkdownDescription: "Gb"}, - "vm_disk": schema.Int64Attribute{Optional: true, MarkdownDescription: "Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму"}, - "ip_space_name": schema.StringAttribute{Optional: true, MarkdownDescription: "no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev"}, - "access_ip_list": schema.StringAttribute{Optional: true, MarkdownDescription: "Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"]"}, - "image_vm": schema.StringAttribute{Required: true}, - "user_login": schema.StringAttribute{Required: true, MarkdownDescription: "Учётка SSH"}, - "user_public_key": schema.StringAttribute{Required: true, MarkdownDescription: "Публичная часть SSH-Ключа для пользователя"}, - "cloud_init": schema.StringAttribute{Optional: true, MarkdownDescription: "Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов."}, - "access_port_list": schema.StringAttribute{Optional: true, MarkdownDescription: "По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmV3RedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVmV3RedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.VmName.IsNull() || plan.VmName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vm_name is required.") - return - } - if plan.VmCpu.IsNull() || plan.VmCpu.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vm_cpu is required.") - return - } - if plan.VmRam.IsNull() || plan.VmRam.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vm_ram is required.") - return - } - if plan.ImageVm.IsNull() || plan.ImageVm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.") - return - } - if plan.UserLogin.IsNull() || plan.UserLogin.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_login is required.") - return - } - if plan.UserPublicKey.IsNull() || plan.UserPublicKey.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.") - return - } - - instanceUID := strings.TrimSpace(plan.VcVmV3ID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vmName": resources_core.FormatString(plan.VmName), - "vmCpu": resources_core.FormatInt64(plan.VmCpu), - "vmRam": resources_core.FormatInt64(plan.VmRam), - "vmDisk": resources_core.FormatInt64(plan.VmDisk), - "ipSpaceName": resources_core.FormatString(plan.IpSpaceName), - "accessIpList": resources_core.FormatString(plan.AccessIpList), - "imageVm": resources_core.FormatString(plan.ImageVm), - "userLogin": resources_core.FormatString(plan.UserLogin), - "userPublicKey": resources_core.FormatString(plan.UserPublicKey), - "cloudInit": resources_core.FormatString(plan.CloudInit), - "accessPortList": resources_core.FormatString(plan.AccessPortList), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVmV3RedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmV3RedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV3RedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmV3RedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVmV3ID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vmName": resources_core.FormatString(plan.VmName), - "vmCpu": resources_core.FormatInt64(plan.VmCpu), - "vmRam": resources_core.FormatInt64(plan.VmRam), - "vmDisk": resources_core.FormatInt64(plan.VmDisk), - "ipSpaceName": resources_core.FormatString(plan.IpSpaceName), - "accessIpList": resources_core.FormatString(plan.AccessIpList), - "imageVm": resources_core.FormatString(plan.ImageVm), - "userLogin": resources_core.FormatString(plan.UserLogin), - "userPublicKey": resources_core.FormatString(plan.UserPublicKey), - "cloudInit": resources_core.FormatString(plan.CloudInit), - "accessPortList": resources_core.FormatString(plan.AccessPortList), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVmV3RedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVmV3RedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/28_vc_vm_v3_resource.go b/generated/prod/go/28_vc_vm_v3_resource.go deleted file mode 100644 index f22a472..0000000 --- a/generated/prod/go/28_vc_vm_v3_resource.go +++ /dev/null @@ -1,586 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm_v3 -// Service ID: 28 - -var _ resource.Resource = &VcVmV3Resource{} -var _ resource.ResourceWithModifyPlan = &VcVmV3Resource{} -var _ resource.ResourceWithImportState = &VcVmV3Resource{} - -type VcVmV3Resource struct { - client *core.UniversalClient -} - -type VcVmV3Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AccessIpList types.String `tfsdk:"access_ip_list"` - AccessPortList types.String `tfsdk:"access_port_list"` - CloudInit types.String `tfsdk:"cloud_init"` - ImageVm types.String `tfsdk:"image_vm"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - UserLogin types.String `tfsdk:"user_login"` - UserPublicKey types.String `tfsdk:"user_public_key"` - VappUid types.String `tfsdk:"vapp_uid"` - VmCpu types.Int64 `tfsdk:"vm_cpu"` - VmDisk types.Int64 `tfsdk:"vm_disk"` - VmName types.String `tfsdk:"vm_name"` - VmRam types.Int64 `tfsdk:"vm_ram"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVmV3Resource() resource.Resource { - return &VcVmV3Resource{} -} - -func (r *VcVmV3Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm_v3" -} - -func (r *VcVmV3Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "access_ip_list": schema.StringAttribute{Optional: true, MarkdownDescription: "Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"]"}, - "access_port_list": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[\"22\"]"), MarkdownDescription: "По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX"}, - "cloud_init": schema.StringAttribute{Optional: true, MarkdownDescription: "Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. Не изменяется после создания."}, - "image_vm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "ip_space_name": schema.StringAttribute{Required: true}, - "user_login": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("myuser"), MarkdownDescription: "Учётка SSH Не изменяется после создания."}, - "user_public_key": schema.StringAttribute{Required: true, MarkdownDescription: "Публичная часть SSH-Ключа для пользователя Не изменяется после создания."}, - "vapp_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=26 (mapped to UUID in core) Не изменяется после создания."}, - "vm_cpu": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "шт"}, - "vm_disk": schema.Int64Attribute{Optional: true, MarkdownDescription: "Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму"}, - "vm_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Не изменяется после создания."}, - "vm_ram": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Gb"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmV3Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVmV3Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, plan.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != plan.VappUid.ValueString() { - plan.VappUid = types.StringValue(resolvedVappUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.CloudInit.IsNull() && !plan.CloudInit.IsUnknown() && !state.CloudInit.IsNull() && !state.CloudInit.IsUnknown() { - if plan.CloudInit.ValueString() != state.CloudInit.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить cloud_init", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ImageVm.IsNull() && !plan.ImageVm.IsUnknown() && !state.ImageVm.IsNull() && !state.ImageVm.IsUnknown() { - if plan.ImageVm.ValueString() != state.ImageVm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить image_vm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserLogin.IsNull() && !plan.UserLogin.IsUnknown() && !state.UserLogin.IsNull() && !state.UserLogin.IsUnknown() { - if plan.UserLogin.ValueString() != state.UserLogin.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить user_login", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserPublicKey.IsNull() && !plan.UserPublicKey.IsUnknown() && !state.UserPublicKey.IsNull() && !state.UserPublicKey.IsUnknown() { - if plan.UserPublicKey.ValueString() != state.UserPublicKey.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить user_public_key", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - if plan.VappUid.ValueString() != state.VappUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vapp_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VmName.IsNull() && !plan.VmName.IsUnknown() && !state.VmName.IsNull() && !state.VmName.IsUnknown() { - if plan.VmName.ValueString() != state.VmName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vm_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ImageVm.IsNull() || config.ImageVm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.") - return - } - if config.IpSpaceName.IsNull() || config.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if config.UserPublicKey.IsNull() || config.UserPublicKey.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.") - return - } - if config.VappUid.IsNull() || config.VappUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VappUid.IsNull() && !config.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, config.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != config.VappUid.ValueString() { - config.VappUid = types.StringValue(resolvedVappUid) - } - } - params := map[int]string{ - 407: resources_core.FormatString(config.VappUid), - 408: resources_core.FormatString(config.VmName), - 409: resources_core.FormatInt64(config.VmCpu), - 410: resources_core.FormatInt64(config.VmRam), - 411: resources_core.FormatInt64(config.VmDisk), - 412: resources_core.FormatString(config.IpSpaceName), - 413: resources_core.FormatString(config.AccessIpList), - 414: resources_core.FormatString(config.ImageVm), - 415: resources_core.FormatString(config.CloudInit), - 416: resources_core.FormatString(config.UserLogin), - 417: resources_core.FormatString(config.UserPublicKey), - 448: resources_core.FormatString(config.AccessPortList), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 28, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVmV3Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ImageVm.IsNull() || data.ImageVm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.") - return - } - if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if data.UserPublicKey.IsNull() || data.UserPublicKey.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.") - return - } - if data.VappUid.IsNull() || data.VappUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - if !data.VappUid.IsNull() && !data.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, data.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVappUid != "" && resolvedVappUid != data.VappUid.ValueString() { - data.VappUid = types.StringValue(resolvedVappUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 28, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 407: resources_core.FormatString(data.VappUid), - 408: resources_core.FormatString(data.VmName), - 409: resources_core.FormatInt64(data.VmCpu), - 410: resources_core.FormatInt64(data.VmRam), - 411: resources_core.FormatInt64(data.VmDisk), - 412: resources_core.FormatString(data.IpSpaceName), - 413: resources_core.FormatString(data.AccessIpList), - 414: resources_core.FormatString(data.ImageVm), - 415: resources_core.FormatString(data.CloudInit), - 416: resources_core.FormatString(data.UserLogin), - 417: resources_core.FormatString(data.UserPublicKey), - 448: resources_core.FormatString(data.AccessPortList), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 28, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 28, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV3Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 28, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VappUid.IsNull() && !newState.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, newState.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != newState.VappUid.ValueString() { - newState.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVmV3Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmV3Model - var state VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.VmCpu.IsNull() != state.VmCpu.IsNull() || plan.VmCpu.IsUnknown() != state.VmCpu.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmCpu.IsNull() && !plan.VmCpu.IsUnknown() && !state.VmCpu.IsNull() && !state.VmCpu.IsUnknown() { - if plan.VmCpu.ValueInt64() != state.VmCpu.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmRam.IsNull() != state.VmRam.IsNull() || plan.VmRam.IsUnknown() != state.VmRam.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmRam.IsNull() && !plan.VmRam.IsUnknown() && !state.VmRam.IsNull() && !state.VmRam.IsUnknown() { - if plan.VmRam.ValueInt64() != state.VmRam.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmDisk.IsNull() != state.VmDisk.IsNull() || plan.VmDisk.IsUnknown() != state.VmDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmDisk.IsNull() && !plan.VmDisk.IsUnknown() && !state.VmDisk.IsNull() && !state.VmDisk.IsUnknown() { - if plan.VmDisk.ValueInt64() != state.VmDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if plan.IpSpaceName.ValueString() != state.IpSpaceName.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessIpList.IsNull() != state.AccessIpList.IsNull() || plan.AccessIpList.IsUnknown() != state.AccessIpList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessIpList.IsNull() && !plan.AccessIpList.IsUnknown() && !state.AccessIpList.IsNull() && !state.AccessIpList.IsUnknown() { - if plan.AccessIpList.ValueString() != state.AccessIpList.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessPortList.IsNull() != state.AccessPortList.IsNull() || plan.AccessPortList.IsUnknown() != state.AccessPortList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessPortList.IsNull() && !plan.AccessPortList.IsUnknown() && !state.AccessPortList.IsNull() && !state.AccessPortList.IsUnknown() { - if plan.AccessPortList.ValueString() != state.AccessPortList.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 493: resources_core.FormatInt64(plan.VmCpu), - 494: resources_core.FormatInt64(plan.VmRam), - 495: resources_core.FormatInt64(plan.VmDisk), - 496: resources_core.FormatString(plan.IpSpaceName), - 497: resources_core.FormatString(plan.AccessIpList), - 498: resources_core.FormatString(plan.AccessPortList), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 28, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV3Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVmV3Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVmV3Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/29_vc_vdc_group_add_vdc_action.go b/generated/prod/go/29_vc_vdc_group_add_vdc_action.go deleted file mode 100644 index 5f1a8d9..0000000 --- a/generated/prod/go/29_vc_vdc_group_add_vdc_action.go +++ /dev/null @@ -1,141 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Action: add_vdc - -var _ resource.Resource = &VcVdcGroupAddVdcResource{} - -// VcVdcGroupAddVdcResource triggers a one-time action. -type VcVdcGroupAddVdcResource struct { - client *core.UniversalClient -} - -type VcVdcGroupAddVdcModel struct { - ID types.String `tfsdk:"id"` - VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - VdcUid types.String `tfsdk:"vdc_uid"` -} - -func NewVcVdcGroupAddVdcResource() resource.Resource { - return &VcVdcGroupAddVdcResource{} -} - -func (r *VcVdcGroupAddVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_add_vdc" -} - -func (r *VcVdcGroupAddVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vdc_group_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=21 (mapped to UUID in core)"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupAddVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcGroupAddVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.VdcUid.IsNull() || plan.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vdcUid": resources_core.FormatString(plan.VdcUid), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "add_vdc", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "add_vdc", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupAddVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupAddVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupAddVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupAddVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vdcUid": resources_core.FormatString(plan.VdcUid), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "add_vdc", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "add_vdc", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupAddVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVdcGroupAddVdcResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/29_vc_vdc_group_reconcile_action.go b/generated/prod/go/29_vc_vdc_group_reconcile_action.go deleted file mode 100644 index 2f08406..0000000 --- a/generated/prod/go/29_vc_vdc_group_reconcile_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Action: reconcile - -var _ resource.Resource = &VcVdcGroupReconcileResource{} - -// VcVdcGroupReconcileResource triggers a one-time action. -type VcVdcGroupReconcileResource struct { - client *core.UniversalClient -} - -type VcVdcGroupReconcileModel struct { - ID types.String `tfsdk:"id"` - VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewVcVdcGroupReconcileResource() resource.Resource { - return &VcVdcGroupReconcileResource{} -} - -func (r *VcVdcGroupReconcileResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_reconcile" -} - -func (r *VcVdcGroupReconcileResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vdc_group_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupReconcileResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcGroupReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "reconcile", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupReconcileResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupReconcileModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupReconcileResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupReconcileModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "reconcile", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "reconcile", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupReconcileResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVdcGroupReconcileResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/29_vc_vdc_group_remove_vdc_action.go b/generated/prod/go/29_vc_vdc_group_remove_vdc_action.go deleted file mode 100644 index af5945f..0000000 --- a/generated/prod/go/29_vc_vdc_group_remove_vdc_action.go +++ /dev/null @@ -1,141 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Action: remove_vdc - -var _ resource.Resource = &VcVdcGroupRemoveVdcResource{} - -// VcVdcGroupRemoveVdcResource triggers a one-time action. -type VcVdcGroupRemoveVdcResource struct { - client *core.UniversalClient -} - -type VcVdcGroupRemoveVdcModel struct { - ID types.String `tfsdk:"id"` - VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - VdcName types.String `tfsdk:"vdc_name"` -} - -func NewVcVdcGroupRemoveVdcResource() resource.Resource { - return &VcVdcGroupRemoveVdcResource{} -} - -func (r *VcVdcGroupRemoveVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_remove_vdc" -} - -func (r *VcVdcGroupRemoveVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "vc_vdc_group_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "vdc_name": schema.StringAttribute{Required: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupRemoveVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcGroupRemoveVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.VdcName.IsNull() || plan.VdcName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_name is required.") - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vdcName": resources_core.FormatString(plan.VdcName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "remove_vdc", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "remove_vdc", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupRemoveVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupRemoveVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupRemoveVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupRemoveVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "vdcName": resources_core.FormatString(plan.VdcName), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "remove_vdc", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "remove_vdc", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupRemoveVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *VcVdcGroupRemoveVdcResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/29_vc_vdc_group_resource.go b/generated/prod/go/29_vc_vdc_group_resource.go deleted file mode 100644 index 61f0b6e..0000000 --- a/generated/prod/go/29_vc_vdc_group_resource.go +++ /dev/null @@ -1,389 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Service ID: 29 - -var _ resource.Resource = &VcVdcGroupResource{} -var _ resource.ResourceWithModifyPlan = &VcVdcGroupResource{} -var _ resource.ResourceWithImportState = &VcVdcGroupResource{} - -type VcVdcGroupResource struct { - client *core.UniversalClient -} - -type VcVdcGroupModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - VdcUid types.String `tfsdk:"vdc_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVdcGroupResource() resource.Resource { - return &VcVdcGroupResource{} -} - -func (r *VcVdcGroupResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group" -} - -func (r *VcVdcGroupResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=21 (mapped to UUID in core) Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVdcGroupModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() { - plan.VdcUid = types.StringValue(resolvedVdcUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if plan.VdcUid.ValueString() != state.VdcUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 618: resources_core.FormatString(config.VdcUid), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 29, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVdcGroupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 29, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 618: resources_core.FormatString(data.VdcUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 29, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 29, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 29, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVdcGroupResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupModel - var state VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 29, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVdcGroupResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVdcGroupResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/2_template_resource.go b/generated/prod/go/2_template_resource.go deleted file mode 100644 index ce37872..0000000 --- a/generated/prod/go/2_template_resource.go +++ /dev/null @@ -1,424 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: template -// Service ID: 2 - -var _ resource.Resource = &TemplateResource{} -var _ resource.ResourceWithModifyPlan = &TemplateResource{} -var _ resource.ResourceWithImportState = &TemplateResource{} - -type TemplateResource struct { - client *core.UniversalClient -} - -type TemplateModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewTemplateResource() resource.Resource { - return &TemplateResource{} -} - -func (r *TemplateResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_template" -} - -func (r *TemplateResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100)}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200)}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *TemplateResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *TemplateModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 202: resources_core.FormatInt64(config.ResourceCPU), - 203: resources_core.FormatInt64(config.ResourceMemory), - 204: resources_core.FormatInt64(config.ResourceDisk), - 205: resources_core.FormatInt64(config.ResourceInstances), - 206: resources_core.FormatString(config.ResourceRealm), - 207: resources_core.FormatString(config.Domain), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 2, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *TemplateResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 2, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 202: resources_core.FormatInt64(data.ResourceCPU), - 203: resources_core.FormatInt64(data.ResourceMemory), - 204: resources_core.FormatInt64(data.ResourceDisk), - 205: resources_core.FormatInt64(data.ResourceInstances), - 206: resources_core.FormatString(data.ResourceRealm), - 207: resources_core.FormatString(data.Domain), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 2, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 2, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TemplateResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 2, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *TemplateResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan TemplateModel - var state TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 208: resources_core.FormatInt64(plan.ResourceCPU), - 209: resources_core.FormatInt64(plan.ResourceMemory), - 210: resources_core.FormatInt64(plan.ResourceDisk), - 211: resources_core.FormatInt64(plan.ResourceInstances), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 2, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TemplateResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *TemplateResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *TemplateResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/32_vmpostgre_resource.go b/generated/prod/go/32_vmpostgre_resource.go deleted file mode 100644 index d3b40f8..0000000 --- a/generated/prod/go/32_vmpostgre_resource.go +++ /dev/null @@ -1,594 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vmpostgre -// Service ID: 32 - -var _ resource.Resource = &VmpostgreResource{} -var _ resource.ResourceWithModifyPlan = &VmpostgreResource{} -var _ resource.ResourceWithImportState = &VmpostgreResource{} - -type VmpostgreResource struct { - client *core.UniversalClient -} - -type VmpostgreModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - NsxtUid types.String `tfsdk:"nsxt_uid"` - ResourceRealm types.String `tfsdk:"resource_realm"` - UserDb types.String `tfsdk:"user_db"` - UserLogin types.String `tfsdk:"user_login"` - UserPassword types.String `tfsdk:"user_password"` - VdcUid types.String `tfsdk:"vdc_uid"` - VmUid types.String `tfsdk:"vm_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVmpostgreResource() resource.Resource { - return &VmpostgreResource{} -} - -func (r *VmpostgreResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vmpostgre" -} - -func (r *VmpostgreResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "nsxt_uid": schema.StringAttribute{Required: true, MarkdownDescription: "InstanceUid nsxt. Nsxt должен быть создан
Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Ресурсная платформа Не изменяется после создания."}, - "user_db": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("servicedb"), MarkdownDescription: "Наименование Базы данных
Не изменяется после создания."}, - "user_login": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("serviceuser"), MarkdownDescription: "Пользователь базы данных
Не изменяется после создания."}, - "user_password": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("fj29gm48fm!d374mc9"), MarkdownDescription: "Пароль от доступа к Базе данных
Не изменяется после создания."}, - "vdc_uid": schema.StringAttribute{Required: true, MarkdownDescription: "InstanceUid vdc. Vdc должен быть создан
Не изменяется после создания."}, - "vm_uid": schema.StringAttribute{Required: true, MarkdownDescription: "InstanceUid ВМ. ВМ должна быть создана
Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VmpostgreResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VmpostgreModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VmpostgreModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VmpostgreModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, plan.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != plan.NsxtUid.ValueString() { - plan.NsxtUid = types.StringValue(resolvedNsxtUid) - planChanged = true - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, plan.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != plan.VdcUid.ValueString() { - plan.VdcUid = types.StringValue(resolvedVdcUid) - planChanged = true - } - } - if !plan.VmUid.IsNull() && !plan.VmUid.IsUnknown() { - resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, plan.VmUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error()) - } else if resolvedVmUid != "" && resolvedVmUid != plan.VmUid.ValueString() { - plan.VmUid = types.StringValue(resolvedVmUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - if plan.NsxtUid.ValueString() != state.NsxtUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить nsxt_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserDb.IsNull() && !plan.UserDb.IsUnknown() && !state.UserDb.IsNull() && !state.UserDb.IsUnknown() { - if plan.UserDb.ValueString() != state.UserDb.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить user_db", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserLogin.IsNull() && !plan.UserLogin.IsUnknown() && !state.UserLogin.IsNull() && !state.UserLogin.IsUnknown() { - if plan.UserLogin.ValueString() != state.UserLogin.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить user_login", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserPassword.IsNull() && !plan.UserPassword.IsUnknown() && !state.UserPassword.IsNull() && !state.UserPassword.IsUnknown() { - if plan.UserPassword.ValueString() != state.UserPassword.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить user_password", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if plan.VdcUid.ValueString() != state.VdcUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VmUid.IsNull() && !plan.VmUid.IsUnknown() && !state.VmUid.IsNull() && !state.VmUid.IsUnknown() { - if plan.VmUid.ValueString() != state.VmUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить vm_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.NsxtUid.IsNull() || config.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.VdcUid.IsNull() || config.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if config.VmUid.IsNull() || config.VmUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vm_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.NsxtUid.IsNull() && !config.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, config.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != config.NsxtUid.ValueString() { - config.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - if !config.VmUid.IsNull() && !config.VmUid.IsUnknown() { - resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, config.VmUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error()) - } else if resolvedVmUid != "" && resolvedVmUid != config.VmUid.ValueString() { - config.VmUid = types.StringValue(resolvedVmUid) - } - } - params := map[int]string{ - 43: resources_core.FormatString(config.VdcUid), - 44: resources_core.FormatString(config.NsxtUid), - 45: resources_core.FormatString(config.VmUid), - 46: resources_core.FormatString(config.UserDb), - 47: resources_core.FormatString(config.UserLogin), - 48: resources_core.FormatString(config.UserPassword), - 859: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 32, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VmpostgreResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VmpostgreModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.NsxtUid.IsNull() || data.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if data.VmUid.IsNull() || data.VmUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vm_uid is required.") - return - } - if !data.NsxtUid.IsNull() && !data.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, data.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedNsxtUid != "" && resolvedNsxtUid != data.NsxtUid.ValueString() { - data.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - if !data.VmUid.IsNull() && !data.VmUid.IsUnknown() { - resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, data.VmUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVmUid != "" && resolvedVmUid != data.VmUid.ValueString() { - data.VmUid = types.StringValue(resolvedVmUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 32, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 43: resources_core.FormatString(data.VdcUid), - 44: resources_core.FormatString(data.NsxtUid), - 45: resources_core.FormatString(data.VmUid), - 46: resources_core.FormatString(data.UserDb), - 47: resources_core.FormatString(data.UserLogin), - 48: resources_core.FormatString(data.UserPassword), - 859: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 32, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 32, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "userDb", Field: "UserDb", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPassword", Field: "UserPassword", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "vmUid", Field: "VmUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - if !state.VmUid.IsNull() && !state.VmUid.IsUnknown() { - resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, state.VmUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error()) - } else if resolvedVmUid != "" && resolvedVmUid != state.VmUid.ValueString() { - state.VmUid = types.StringValue(resolvedVmUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VmpostgreResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VmpostgreModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 32, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "userDb", Field: "UserDb", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPassword", Field: "UserPassword", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "vmUid", Field: "VmUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.NsxtUid.IsNull() && !newState.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, newState.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != newState.NsxtUid.ValueString() { - newState.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - if !newState.VmUid.IsNull() && !newState.VmUid.IsUnknown() { - resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, newState.VmUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error()) - } else if resolvedVmUid != "" && resolvedVmUid != newState.VmUid.ValueString() { - newState.VmUid = types.StringValue(resolvedVmUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VmpostgreResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VmpostgreModel - var state VmpostgreModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 32, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "userDb", Field: "UserDb", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPassword", Field: "UserPassword", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "vmUid", Field: "VmUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - if !state.VmUid.IsNull() && !state.VmUid.IsUnknown() { - resolvedVmUid, err := r.client.ResolveRefSvcParamValue(ctx, 23, state.VmUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vm_uid", err.Error()) - } else if resolvedVmUid != "" && resolvedVmUid != state.VmUid.ValueString() { - state.VmUid = types.StringValue(resolvedVmUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VmpostgreResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VmpostgreModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VmpostgreResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VmpostgreResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/50_nextcloud_resource.go b/generated/prod/go/50_nextcloud_resource.go deleted file mode 100644 index b5938d0..0000000 --- a/generated/prod/go/50_nextcloud_resource.go +++ /dev/null @@ -1,584 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nextcloud -// Service ID: 50 - -var _ resource.Resource = &NextcloudResource{} -var _ resource.ResourceWithModifyPlan = &NextcloudResource{} -var _ resource.ResourceWithImportState = &NextcloudResource{} - -type NextcloudResource struct { - client *core.UniversalClient -} - -type NextcloudModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AppVersion types.String `tfsdk:"app_version"` - DocumentServer types.String `tfsdk:"document_server"` - Domain types.String `tfsdk:"domain"` - PsqlUid types.String `tfsdk:"psql_uid"` - RedisUid types.String `tfsdk:"redis_uid"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNextcloudResource() resource.Resource { - return &NextcloudResource{} -} - -func (r *NextcloudResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nextcloud" -} - -func (r *NextcloudResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("32.0.1")}, - "document_server": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("collabora"), MarkdownDescription: "Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен
Размер пода collabora:
1.8 ядра. 2Gi ОЗУ Не изменяется после создания."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "psql_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=90 (mapped to UUID in core) Не изменяется после создания."}, - "redis_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UI display_name for service_id=91 (mapped to UUID in core) Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(2), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)
Диск не может быть меньше 2G (!)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов
Не может пока быть больше одного, так как нужны SC под RWMany"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NextcloudResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NextcloudModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, plan.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != plan.PsqlUid.ValueString() { - plan.PsqlUid = types.StringValue(resolvedPsqlUid) - planChanged = true - } - } - if !plan.RedisUid.IsNull() && !plan.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, plan.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != plan.RedisUid.ValueString() { - plan.RedisUid = types.StringValue(resolvedRedisUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.DocumentServer.IsNull() && !plan.DocumentServer.IsUnknown() && !state.DocumentServer.IsNull() && !state.DocumentServer.IsUnknown() { - if plan.DocumentServer.ValueString() != state.DocumentServer.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить document_server", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - if plan.PsqlUid.ValueString() != state.PsqlUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить psql_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RedisUid.IsNull() && !plan.RedisUid.IsUnknown() && !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() { - if plan.RedisUid.ValueString() != state.RedisUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить redis_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.PsqlUid.IsNull() || config.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - if config.RedisUid.IsNull() || config.RedisUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "redis_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.PsqlUid.IsNull() && !config.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, config.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != config.PsqlUid.ValueString() { - config.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !config.RedisUid.IsNull() && !config.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, config.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != config.RedisUid.ValueString() { - config.RedisUid = types.StringValue(resolvedRedisUid) - } - } - params := map[int]string{ - 21: resources_core.FormatString(config.Domain), - 99: resources_core.FormatInt64(config.ResourceCPU), - 100: resources_core.FormatInt64(config.ResourceMemory), - 101: resources_core.FormatInt64(config.ResourceDisk), - 192: resources_core.FormatString(config.DocumentServer), - 470: resources_core.FormatInt64(config.ResourceInstances), - 564: resources_core.FormatString(config.PsqlUid), - 569: resources_core.FormatString(config.AppVersion), - 570: resources_core.FormatString(config.RedisUid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 50, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NextcloudResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.PsqlUid.IsNull() || data.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - if data.RedisUid.IsNull() || data.RedisUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "redis_uid is required.") - return - } - if !data.PsqlUid.IsNull() && !data.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, data.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedPsqlUid != "" && resolvedPsqlUid != data.PsqlUid.ValueString() { - data.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !data.RedisUid.IsNull() && !data.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, data.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedRedisUid != "" && resolvedRedisUid != data.RedisUid.ValueString() { - data.RedisUid = types.StringValue(resolvedRedisUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 50, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 21: resources_core.FormatString(data.Domain), - 99: resources_core.FormatInt64(data.ResourceCPU), - 100: resources_core.FormatInt64(data.ResourceMemory), - 101: resources_core.FormatInt64(data.ResourceDisk), - 192: resources_core.FormatString(data.DocumentServer), - 470: resources_core.FormatInt64(data.ResourceInstances), - 564: resources_core.FormatString(data.PsqlUid), - 569: resources_core.FormatString(data.AppVersion), - 570: resources_core.FormatString(data.RedisUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 50, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 50, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "documentServer", Field: "DocumentServer", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "redisUid", Field: "RedisUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, state.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != state.RedisUid.ValueString() { - state.RedisUid = types.StringValue(resolvedRedisUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 50, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "documentServer", Field: "DocumentServer", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "redisUid", Field: "RedisUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.PsqlUid.IsNull() && !newState.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, newState.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != newState.PsqlUid.ValueString() { - newState.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !newState.RedisUid.IsNull() && !newState.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, newState.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != newState.RedisUid.ValueString() { - newState.RedisUid = types.StringValue(resolvedRedisUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NextcloudResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NextcloudModel - var state NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 178: resources_core.FormatInt64(plan.ResourceCPU), - 179: resources_core.FormatInt64(plan.ResourceMemory), - 180: resources_core.FormatInt64(plan.ResourceDisk), - 547: resources_core.FormatInt64(plan.ResourceInstances), - 571: resources_core.FormatString(plan.AppVersion), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 50, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "documentServer", Field: "DocumentServer", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "redisUid", Field: "RedisUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - if !state.RedisUid.IsNull() && !state.RedisUid.IsUnknown() { - resolvedRedisUid, err := r.client.ResolveRefSvcParamValue(ctx, 91, state.RedisUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve redis_uid", err.Error()) - } else if resolvedRedisUid != "" && resolvedRedisUid != state.RedisUid.ValueString() { - state.RedisUid = types.StringValue(resolvedRedisUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NextcloudResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NextcloudResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/50_nextcloud_restart_action.go b/generated/prod/go/50_nextcloud_restart_action.go deleted file mode 100644 index a3c0260..0000000 --- a/generated/prod/go/50_nextcloud_restart_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nextcloud -// Action: restart - -var _ resource.Resource = &NextcloudRestartResource{} - -// NextcloudRestartResource triggers a one-time action. -type NextcloudRestartResource struct { - client *core.UniversalClient -} - -type NextcloudRestartModel struct { - ID types.String `tfsdk:"id"` - NextcloudID types.String `tfsdk:"nextcloud_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewNextcloudRestartResource() resource.Resource { - return &NextcloudRestartResource{} -} - -func (r *NextcloudRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nextcloud_restart" -} - -func (r *NextcloudRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "nextcloud_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NextcloudRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan NextcloudRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.NextcloudID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NextcloudRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NextcloudRestartModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NextcloudRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.NextcloudID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NextcloudRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *NextcloudRestartResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/81_superset_resource.go b/generated/prod/go/81_superset_resource.go deleted file mode 100644 index 5dcb375..0000000 --- a/generated/prod/go/81_superset_resource.go +++ /dev/null @@ -1,417 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: superset -// Service ID: 81 - -var _ resource.Resource = &SupersetResource{} -var _ resource.ResourceWithModifyPlan = &SupersetResource{} -var _ resource.ResourceWithImportState = &SupersetResource{} - -type SupersetResource struct { - client *core.UniversalClient -} - -type SupersetModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - Emails types.String `tfsdk:"emails"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewSupersetResource() resource.Resource { - return &SupersetResource{} -} - -func (r *SupersetResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_superset" -} - -func (r *SupersetResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "emails": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("testuser1"), MarkdownDescription: "Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *SupersetResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *SupersetModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Emails.IsNull() && !plan.Emails.IsUnknown() && !state.Emails.IsNull() && !state.Emails.IsUnknown() { - if plan.Emails.ValueString() != state.Emails.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить emails", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 14: resources_core.FormatString(config.Domain), - 20: resources_core.FormatString(config.Emails), - 96: resources_core.FormatInt64(config.ResourceCPU), - 97: resources_core.FormatInt64(config.ResourceMemory), - 98: resources_core.FormatInt64(config.ResourceDisk), - 109: resources_core.FormatString(config.ResourceRealm), - 227: resources_core.FormatInt64(config.ResourceInstances), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 81, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *SupersetResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 81, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 14: resources_core.FormatString(data.Domain), - 20: resources_core.FormatString(data.Emails), - 96: resources_core.FormatInt64(data.ResourceCPU), - 97: resources_core.FormatInt64(data.ResourceMemory), - 98: resources_core.FormatInt64(data.ResourceDisk), - 109: resources_core.FormatString(data.ResourceRealm), - 227: resources_core.FormatInt64(data.ResourceInstances), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 81, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 81, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *SupersetResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 81, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *SupersetResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan SupersetModel - var state SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 81, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *SupersetResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *SupersetResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *SupersetResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/82_harbor_resource.go b/generated/prod/go/82_harbor_resource.go deleted file mode 100644 index ef19c23..0000000 --- a/generated/prod/go/82_harbor_resource.go +++ /dev/null @@ -1,446 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: harbor -// Service ID: 82 - -var _ resource.Resource = &HarborResource{} -var _ resource.ResourceWithModifyPlan = &HarborResource{} -var _ resource.ResourceWithImportState = &HarborResource{} - -type HarborResource struct { - client *core.UniversalClient -} - -type HarborModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - Emails types.String `tfsdk:"emails"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewHarborResource() resource.Resource { - return &HarborResource{} -} - -func (r *HarborResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_harbor" -} - -func (r *HarborResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "emails": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("testuser1"), MarkdownDescription: "Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID экземпляра услуги S3 Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *HarborResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *HarborModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() { - plan.S3Uid = types.StringValue(resolvedS3Uid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Emails.IsNull() && !plan.Emails.IsUnknown() && !state.Emails.IsNull() && !state.Emails.IsUnknown() { - if plan.Emails.ValueString() != state.Emails.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить emails", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - if plan.S3Uid.ValueString() != state.S3Uid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 16: resources_core.FormatString(config.Domain), - 17: resources_core.FormatString(config.Emails), - 110: resources_core.FormatString(config.ResourceRealm), - 228: resources_core.FormatInt64(config.ResourceCPU), - 229: resources_core.FormatInt64(config.ResourceMemory), - 230: resources_core.FormatInt64(config.ResourceInstances), - 231: resources_core.FormatString(config.S3Uid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 82, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *HarborResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 82, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 16: resources_core.FormatString(data.Domain), - 17: resources_core.FormatString(data.Emails), - 110: resources_core.FormatString(data.ResourceRealm), - 228: resources_core.FormatInt64(data.ResourceCPU), - 229: resources_core.FormatInt64(data.ResourceMemory), - 230: resources_core.FormatInt64(data.ResourceInstances), - 231: resources_core.FormatString(data.S3Uid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 82, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 82, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HarborResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 82, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *HarborResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan HarborModel - var state HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 82, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HarborResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *HarborResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *HarborResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/88_k8s_ziti_controller_resource.go b/generated/prod/go/88_k8s_ziti_controller_resource.go deleted file mode 100644 index 7ad4d64..0000000 --- a/generated/prod/go/88_k8s_ziti_controller_resource.go +++ /dev/null @@ -1,404 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_ziti_controller -// Service ID: 88 - -var _ resource.Resource = &K8sZitiControllerResource{} -var _ resource.ResourceWithModifyPlan = &K8sZitiControllerResource{} -var _ resource.ResourceWithImportState = &K8sZitiControllerResource{} - -type K8sZitiControllerResource struct { - client *core.UniversalClient -} - -type K8sZitiControllerModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewK8sZitiControllerResource() resource.Resource { - return &K8sZitiControllerResource{} -} - -func (r *K8sZitiControllerResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_ziti_controller" -} - -func (r *K8sZitiControllerResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores) Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sZitiControllerResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *K8sZitiControllerModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 294: resources_core.FormatInt64(config.ResourceCPU), - 295: resources_core.FormatInt64(config.ResourceMemory), - 296: resources_core.FormatInt64(config.ResourceDisk), - 297: resources_core.FormatInt64(config.ResourceInstances), - 298: resources_core.FormatString(config.ResourceRealm), - 299: resources_core.FormatString(config.Domain), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 88, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *K8sZitiControllerResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 88, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 294: resources_core.FormatInt64(data.ResourceCPU), - 295: resources_core.FormatInt64(data.ResourceMemory), - 296: resources_core.FormatInt64(data.ResourceDisk), - 297: resources_core.FormatInt64(data.ResourceInstances), - 298: resources_core.FormatString(data.ResourceRealm), - 299: resources_core.FormatString(data.Domain), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 88, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 88, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sZitiControllerResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 88, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *K8sZitiControllerResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sZitiControllerModel - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 88, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sZitiControllerResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *K8sZitiControllerResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *K8sZitiControllerResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/89_flask_resource.go b/generated/prod/go/89_flask_resource.go deleted file mode 100644 index 6b11602..0000000 --- a/generated/prod/go/89_flask_resource.go +++ /dev/null @@ -1,454 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: flask -// Service ID: 89 - -var _ resource.Resource = &FlaskResource{} -var _ resource.ResourceWithModifyPlan = &FlaskResource{} -var _ resource.ResourceWithImportState = &FlaskResource{} - -type FlaskResource struct { - client *core.UniversalClient -} - -type FlaskModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - GitPath types.String `tfsdk:"git_path"` - HealthPath types.String `tfsdk:"health_path"` - JsonEnv types.String `tfsdk:"json_env"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewFlaskResource() resource.Resource { - return &FlaskResource{} -} - -func (r *FlaskResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_flask" -} - -func (r *FlaskResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/Foxyhhd/Baldurs-Gate-test.git"), MarkdownDescription: "Путь до Git, который будет webroot для сайта"}, - "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код Не изменяется после создания."}, - "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{ "param": "value" }"), MarkdownDescription: "Массив переменных, будут переданы в env приложения"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(256), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *FlaskResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *FlaskModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() { - if plan.HealthPath.ValueString() != state.HealthPath.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить health_path", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 248: resources_core.FormatString(config.Domain), - 249: resources_core.FormatString(config.ResourceRealm), - 250: resources_core.FormatInt64(config.ResourceCPU), - 251: resources_core.FormatInt64(config.ResourceMemory), - 252: resources_core.FormatInt64(config.ResourceInstances), - 253: resources_core.FormatString(config.GitPath), - 254: resources_core.FormatString(config.JsonEnv), - 255: resources_core.FormatString(config.HealthPath), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 89, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *FlaskResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 89, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 248: resources_core.FormatString(data.Domain), - 249: resources_core.FormatString(data.ResourceRealm), - 250: resources_core.FormatInt64(data.ResourceCPU), - 251: resources_core.FormatInt64(data.ResourceMemory), - 252: resources_core.FormatInt64(data.ResourceInstances), - 253: resources_core.FormatString(data.GitPath), - 254: resources_core.FormatString(data.JsonEnv), - 255: resources_core.FormatString(data.HealthPath), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 89, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 89, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *FlaskResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 89, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *FlaskResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan FlaskModel - var state FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() { - if plan.GitPath.ValueString() != state.GitPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 451: resources_core.FormatInt64(plan.ResourceCPU), - 452: resources_core.FormatInt64(plan.ResourceMemory), - 453: resources_core.FormatInt64(plan.ResourceInstances), - 454: resources_core.FormatString(plan.GitPath), - 455: resources_core.FormatString(plan.JsonEnv), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 89, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *FlaskResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *FlaskResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *FlaskResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/90_postgres_recovery_action.go b/generated/prod/go/90_postgres_recovery_action.go deleted file mode 100644 index edaacb2..0000000 --- a/generated/prod/go/90_postgres_recovery_action.go +++ /dev/null @@ -1,158 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Action: recovery - -var _ resource.Resource = &PostgresRecoveryResource{} - -// PostgresRecoveryResource triggers a one-time action. -type PostgresRecoveryResource struct { - client *core.UniversalClient -} - -type PostgresRecoveryModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewPostgresRecoveryResource() resource.Resource { - return &PostgresRecoveryResource{} -} - -func (r *PostgresRecoveryResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_recovery" -} - -func (r *PostgresRecoveryResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "postgres_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)
"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili)
"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresRecoveryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresRecoveryModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceInstances": resources_core.FormatInt64(plan.ResourceInstances), - "resourceMemory": resources_core.FormatInt64(plan.ResourceMemory), - "resourceCPU": resources_core.FormatInt64(plan.ResourceCPU), - "resourceDisk": resources_core.FormatInt64(plan.ResourceDisk), - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "recovery", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "recovery", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresRecoveryResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresRecoveryModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresRecoveryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresRecoveryModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceInstances": resources_core.FormatInt64(plan.ResourceInstances), - "resourceMemory": resources_core.FormatInt64(plan.ResourceMemory), - "resourceCPU": resources_core.FormatInt64(plan.ResourceCPU), - "resourceDisk": resources_core.FormatInt64(plan.ResourceDisk), - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "recovery", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "recovery", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresRecoveryResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *PostgresRecoveryResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/90_postgres_resource.go b/generated/prod/go/90_postgres_resource.go deleted file mode 100644 index 3d54dce..0000000 --- a/generated/prod/go/90_postgres_resource.go +++ /dev/null @@ -1,686 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Service ID: 90 - -var _ resource.Resource = &PostgresResource{} -var _ resource.ResourceWithModifyPlan = &PostgresResource{} -var _ resource.ResourceWithImportState = &PostgresResource{} - -type PostgresResource struct { - client *core.UniversalClient -} - -type PostgresModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AllowNoSSL types.Bool `tfsdk:"allow_no_s_s_l"` - AppVersion types.String `tfsdk:"app_version"` - AutoScale types.Bool `tfsdk:"auto_scale"` - AutoScalePercentage types.Int64 `tfsdk:"auto_scale_percentage"` - AutoScaleQuotaGb types.String `tfsdk:"auto_scale_quota_gb"` - AutoScaleTechWindow types.Int64 `tfsdk:"auto_scale_tech_window"` - EnablePgPoolerMaster types.Bool `tfsdk:"enable_pg_pooler_master"` - EnablePgPoolerSlave types.Bool `tfsdk:"enable_pg_pooler_slave"` - ExtBACKUPNUMTORETAIN types.Int64 `tfsdk:"ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n"` - ExtBACKUPSCHEDULE types.String `tfsdk:"ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - IpSpaceNameSlave types.String `tfsdk:"ip_space_name_slave"` - JsonParameters types.String `tfsdk:"json_parameters"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - NeedExternalAddressSlave types.Bool `tfsdk:"need_external_address_slave"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.String `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewPostgresResource() resource.Resource { - return &PostgresResource{} -} - -func (r *PostgresResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres" -} - -func (r *PostgresResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "allow_no_s_s_l": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр"}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("17"), MarkdownDescription: "Версия PostgreSQL"}, - "auto_scale": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги Не изменяется после создания."}, - "auto_scale_percentage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема Не изменяется после создания."}, - "auto_scale_quota_gb": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("1"), MarkdownDescription: "Квота для autoScale Не изменяется после создания."}, - "auto_scale_tech_window": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) Не изменяется после создания."}, - "enable_pg_pooler_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает pgPooler (на запись). Будет создан новый под"}, - "enable_pg_pooler_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает pgPooler (на чтение). Будет создан новый под"}, - "ext__b_a_c_k_u_p__n_u_m__t_o__r_e_t_a_i_n": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(7), MarkdownDescription: "Не обязательный. Количество сохраняемых бекапов"}, - "ext__b_a_c_k_u_p__s_c_h_e_d_u_l_e": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("0 0 * * *"), MarkdownDescription: "Не обязательный. Время запуска бекапа"}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`"}, - "ip_space_name_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave"}, - "json_parameters": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{ \"log_connections\": \"off\", \"log_disconnections\": \"off\" }"), MarkdownDescription: "Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к master"}, - "need_external_address_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores)"}, - "resource_disk": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("10"), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Required: true, MarkdownDescription: "Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *PostgresModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, plan.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != plan.S3Uid.ValueString() { - plan.S3Uid = types.StringValue(resolvedS3Uid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AutoScale.IsNull() && !plan.AutoScale.IsUnknown() && !state.AutoScale.IsNull() && !state.AutoScale.IsUnknown() { - if plan.AutoScale.ValueBool() != state.AutoScale.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить auto_scale", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.AutoScalePercentage.IsNull() && !plan.AutoScalePercentage.IsUnknown() && !state.AutoScalePercentage.IsNull() && !state.AutoScalePercentage.IsUnknown() { - if plan.AutoScalePercentage.ValueInt64() != state.AutoScalePercentage.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить auto_scale_percentage", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.AutoScaleQuotaGb.IsNull() && !plan.AutoScaleQuotaGb.IsUnknown() && !state.AutoScaleQuotaGb.IsNull() && !state.AutoScaleQuotaGb.IsUnknown() { - if plan.AutoScaleQuotaGb.ValueString() != state.AutoScaleQuotaGb.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить auto_scale_quota_gb", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.AutoScaleTechWindow.IsNull() && !plan.AutoScaleTechWindow.IsUnknown() && !state.AutoScaleTechWindow.IsNull() && !state.AutoScaleTechWindow.IsUnknown() { - if plan.AutoScaleTechWindow.ValueInt64() != state.AutoScaleTechWindow.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить auto_scale_tech_window", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - if plan.S3Uid.ValueString() != state.S3Uid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.S3Uid.IsNull() || config.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 23: resources_core.FormatString(config.S3Uid), - 80: resources_core.FormatInt64(config.ResourceInstances), - 81: resources_core.FormatInt64(config.ResourceMemory), - 82: resources_core.FormatInt64(config.ResourceCPU), - 83: resources_core.FormatString(config.ResourceDisk), - 102: resources_core.FormatString(config.ResourceRealm), - 145: resources_core.FormatBool(config.NeedExternalAddressMaster), - 146: resources_core.FormatBool(config.NeedExternalAddressSlave), - 265: resources_core.FormatString(config.ExtBACKUPSCHEDULE), - 266: resources_core.FormatInt64(config.ExtBACKUPNUMTORETAIN), - 310: resources_core.FormatString(config.AppVersion), - 311: resources_core.FormatString(config.JsonParameters), - 312: resources_core.FormatBool(config.EnablePgPoolerMaster), - 313: resources_core.FormatBool(config.EnablePgPoolerSlave), - 314: resources_core.FormatBool(config.AllowNoSSL), - 329: resources_core.FormatBool(config.AutoScale), - 330: resources_core.FormatInt64(config.AutoScalePercentage), - 331: resources_core.FormatInt64(config.AutoScaleTechWindow), - 337: resources_core.FormatString(config.IpSpaceNameMaster), - 338: resources_core.FormatString(config.IpSpaceNameSlave), - 339: resources_core.FormatString(config.AutoScaleQuotaGb), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 90, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *PostgresResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 90, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 23: resources_core.FormatString(data.S3Uid), - 80: resources_core.FormatInt64(data.ResourceInstances), - 81: resources_core.FormatInt64(data.ResourceMemory), - 82: resources_core.FormatInt64(data.ResourceCPU), - 83: resources_core.FormatString(data.ResourceDisk), - 102: resources_core.FormatString(data.ResourceRealm), - 145: resources_core.FormatBool(data.NeedExternalAddressMaster), - 146: resources_core.FormatBool(data.NeedExternalAddressSlave), - 265: resources_core.FormatString(data.ExtBACKUPSCHEDULE), - 266: resources_core.FormatInt64(data.ExtBACKUPNUMTORETAIN), - 310: resources_core.FormatString(data.AppVersion), - 311: resources_core.FormatString(data.JsonParameters), - 312: resources_core.FormatBool(data.EnablePgPoolerMaster), - 313: resources_core.FormatBool(data.EnablePgPoolerSlave), - 314: resources_core.FormatBool(data.AllowNoSSL), - 329: resources_core.FormatBool(data.AutoScale), - 330: resources_core.FormatInt64(data.AutoScalePercentage), - 331: resources_core.FormatInt64(data.AutoScaleTechWindow), - 337: resources_core.FormatString(data.IpSpaceNameMaster), - 338: resources_core.FormatString(data.IpSpaceNameSlave), - 339: resources_core.FormatString(data.AutoScaleQuotaGb), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 90, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 90, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"}, - {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "jsonParameters", Field: "JsonParameters", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 90, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"}, - {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "jsonParameters", Field: "JsonParameters", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *PostgresResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresModel - var state PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueString() != state.ResourceDisk.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressSlave.IsNull() != state.NeedExternalAddressSlave.IsNull() || plan.NeedExternalAddressSlave.IsUnknown() != state.NeedExternalAddressSlave.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressSlave.IsNull() && !plan.NeedExternalAddressSlave.IsUnknown() && !state.NeedExternalAddressSlave.IsNull() && !state.NeedExternalAddressSlave.IsUnknown() { - if plan.NeedExternalAddressSlave.ValueBool() != state.NeedExternalAddressSlave.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPSCHEDULE.IsNull() != state.ExtBACKUPSCHEDULE.IsNull() || plan.ExtBACKUPSCHEDULE.IsUnknown() != state.ExtBACKUPSCHEDULE.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPSCHEDULE.IsNull() && !plan.ExtBACKUPSCHEDULE.IsUnknown() && !state.ExtBACKUPSCHEDULE.IsNull() && !state.ExtBACKUPSCHEDULE.IsUnknown() { - if plan.ExtBACKUPSCHEDULE.ValueString() != state.ExtBACKUPSCHEDULE.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ExtBACKUPNUMTORETAIN.IsNull() != state.ExtBACKUPNUMTORETAIN.IsNull() || plan.ExtBACKUPNUMTORETAIN.IsUnknown() != state.ExtBACKUPNUMTORETAIN.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ExtBACKUPNUMTORETAIN.IsNull() && !plan.ExtBACKUPNUMTORETAIN.IsUnknown() && !state.ExtBACKUPNUMTORETAIN.IsNull() && !state.ExtBACKUPNUMTORETAIN.IsUnknown() { - if plan.ExtBACKUPNUMTORETAIN.ValueInt64() != state.ExtBACKUPNUMTORETAIN.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonParameters.IsNull() != state.JsonParameters.IsNull() || plan.JsonParameters.IsUnknown() != state.JsonParameters.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonParameters.IsNull() && !plan.JsonParameters.IsUnknown() && !state.JsonParameters.IsNull() && !state.JsonParameters.IsUnknown() { - if plan.JsonParameters.ValueString() != state.JsonParameters.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.EnablePgPoolerMaster.IsNull() != state.EnablePgPoolerMaster.IsNull() || plan.EnablePgPoolerMaster.IsUnknown() != state.EnablePgPoolerMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.EnablePgPoolerMaster.IsNull() && !plan.EnablePgPoolerMaster.IsUnknown() && !state.EnablePgPoolerMaster.IsNull() && !state.EnablePgPoolerMaster.IsUnknown() { - if plan.EnablePgPoolerMaster.ValueBool() != state.EnablePgPoolerMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.EnablePgPoolerSlave.IsNull() != state.EnablePgPoolerSlave.IsNull() || plan.EnablePgPoolerSlave.IsUnknown() != state.EnablePgPoolerSlave.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.EnablePgPoolerSlave.IsNull() && !plan.EnablePgPoolerSlave.IsUnknown() && !state.EnablePgPoolerSlave.IsNull() && !state.EnablePgPoolerSlave.IsUnknown() { - if plan.EnablePgPoolerSlave.ValueBool() != state.EnablePgPoolerSlave.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AllowNoSSL.IsNull() != state.AllowNoSSL.IsNull() || plan.AllowNoSSL.IsUnknown() != state.AllowNoSSL.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AllowNoSSL.IsNull() && !plan.AllowNoSSL.IsUnknown() && !state.AllowNoSSL.IsNull() && !state.AllowNoSSL.IsUnknown() { - if plan.AllowNoSSL.ValueBool() != state.AllowNoSSL.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameSlave.IsNull() != state.IpSpaceNameSlave.IsNull() || plan.IpSpaceNameSlave.IsUnknown() != state.IpSpaceNameSlave.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameSlave.IsNull() && !plan.IpSpaceNameSlave.IsUnknown() && !state.IpSpaceNameSlave.IsNull() && !state.IpSpaceNameSlave.IsUnknown() { - if plan.IpSpaceNameSlave.ValueString() != state.IpSpaceNameSlave.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 91: resources_core.FormatInt64(plan.ResourceInstances), - 92: resources_core.FormatInt64(plan.ResourceMemory), - 93: resources_core.FormatInt64(plan.ResourceCPU), - 94: resources_core.FormatString(plan.ResourceDisk), - 147: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 148: resources_core.FormatBool(plan.NeedExternalAddressSlave), - 267: resources_core.FormatString(plan.ExtBACKUPSCHEDULE), - 268: resources_core.FormatInt64(plan.ExtBACKUPNUMTORETAIN), - 315: resources_core.FormatString(plan.AppVersion), - 316: resources_core.FormatString(plan.JsonParameters), - 317: resources_core.FormatBool(plan.EnablePgPoolerMaster), - 318: resources_core.FormatBool(plan.EnablePgPoolerSlave), - 319: resources_core.FormatBool(plan.AllowNoSSL), - 541: resources_core.FormatString(plan.IpSpaceNameMaster), - 542: resources_core.FormatString(plan.IpSpaceNameSlave), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 90, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "allowNoSSL", Field: "AllowNoSSL", Type: "bool"}, - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "autoScale", Field: "AutoScale", Type: "bool"}, - {Code: "autoScalePercentage", Field: "AutoScalePercentage", Type: "int64"}, - {Code: "autoScaleQuotaGb", Field: "AutoScaleQuotaGb", Type: "string"}, - {Code: "autoScaleTechWindow", Field: "AutoScaleTechWindow", Type: "int64"}, - {Code: "enablePgPoolerMaster", Field: "EnablePgPoolerMaster", Type: "bool"}, - {Code: "enablePgPoolerSlave", Field: "EnablePgPoolerSlave", Type: "bool"}, - {Code: "ext_BACKUP_NUM_TO_RETAIN", Field: "ExtBACKUPNUMTORETAIN", Type: "int64"}, - {Code: "ext_BACKUP_SCHEDULE", Field: "ExtBACKUPSCHEDULE", Type: "string"}, - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "jsonParameters", Field: "JsonParameters", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "string"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *PostgresResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *PostgresResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/90_postgres_restart_action.go b/generated/prod/go/90_postgres_restart_action.go deleted file mode 100644 index 4d8e202..0000000 --- a/generated/prod/go/90_postgres_restart_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Action: restart - -var _ resource.Resource = &PostgresRestartResource{} - -// PostgresRestartResource triggers a one-time action. -type PostgresRestartResource struct { - client *core.UniversalClient -} - -type PostgresRestartModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewPostgresRestartResource() resource.Resource { - return &PostgresRestartResource{} -} - -func (r *PostgresRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_restart" -} - -func (r *PostgresRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "postgres_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresRestartModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *PostgresRestartResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/91_redis_resource.go b/generated/prod/go/91_redis_resource.go deleted file mode 100644 index bcb9db7..0000000 --- a/generated/prod/go/91_redis_resource.go +++ /dev/null @@ -1,436 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: redis -// Service ID: 91 - -var _ resource.Resource = &RedisResource{} -var _ resource.ResourceWithModifyPlan = &RedisResource{} -var _ resource.ResourceWithImportState = &RedisResource{} - -type RedisResource struct { - client *core.UniversalClient -} - -type RedisModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - IpSpaceNameSlave types.String `tfsdk:"ip_space_name_slave"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - NeedExternalAddressSlave types.Bool `tfsdk:"need_external_address_slave"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewRedisResource() resource.Resource { - return &RedisResource{} -} - -func (r *RedisResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_redis" -} - -func (r *RedisResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster Не изменяется после создания."}, - "ip_space_name_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave Не изменяется после создания."}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний IP для доступа к master Не изменяется после создания."}, - "need_external_address_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Квота ядра пода (Указывается в mili) Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(30), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *RedisResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *RedisModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name_master", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.IpSpaceNameSlave.IsNull() && !plan.IpSpaceNameSlave.IsUnknown() && !state.IpSpaceNameSlave.IsNull() && !state.IpSpaceNameSlave.IsUnknown() { - if plan.IpSpaceNameSlave.ValueString() != state.IpSpaceNameSlave.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name_slave", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_master", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressSlave.IsNull() && !plan.NeedExternalAddressSlave.IsUnknown() && !state.NeedExternalAddressSlave.IsNull() && !state.NeedExternalAddressSlave.IsUnknown() { - if plan.NeedExternalAddressSlave.ValueBool() != state.NeedExternalAddressSlave.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_slave", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 112: resources_core.FormatInt64(config.ResourceCPU), - 113: resources_core.FormatInt64(config.ResourceMemory), - 114: resources_core.FormatInt64(config.ResourceDisk), - 181: resources_core.FormatInt64(config.ResourceInstances), - 182: resources_core.FormatString(config.ResourceRealm), - 183: resources_core.FormatBool(config.NeedExternalAddressMaster), - 184: resources_core.FormatBool(config.NeedExternalAddressSlave), - 548: resources_core.FormatString(config.IpSpaceNameMaster), - 549: resources_core.FormatString(config.IpSpaceNameSlave), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 91, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *RedisResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 91, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 112: resources_core.FormatInt64(data.ResourceCPU), - 113: resources_core.FormatInt64(data.ResourceMemory), - 114: resources_core.FormatInt64(data.ResourceDisk), - 181: resources_core.FormatInt64(data.ResourceInstances), - 182: resources_core.FormatString(data.ResourceRealm), - 183: resources_core.FormatBool(data.NeedExternalAddressMaster), - 184: resources_core.FormatBool(data.NeedExternalAddressSlave), - 548: resources_core.FormatString(data.IpSpaceNameMaster), - 549: resources_core.FormatString(data.IpSpaceNameSlave), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 91, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 91, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RedisResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 91, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *RedisResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan RedisModel - var state RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 91, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RedisResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *RedisResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *RedisResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/92_mongodb_resource.go b/generated/prod/go/92_mongodb_resource.go deleted file mode 100644 index ef456bf..0000000 --- a/generated/prod/go/92_mongodb_resource.go +++ /dev/null @@ -1,445 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mongodb -// Service ID: 92 - -var _ resource.Resource = &MongodbResource{} -var _ resource.ResourceWithModifyPlan = &MongodbResource{} -var _ resource.ResourceWithImportState = &MongodbResource{} - -type MongodbResource struct { - client *core.UniversalClient -} - -type MongodbModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.String `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewMongodbResource() resource.Resource { - return &MongodbResource{} -} - -func (r *MongodbResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mongodb" -} - -func (r *MongodbResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1` Не изменяется после создания."}, - "need_external_address_master": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("false"), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false` Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `1000` Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `20` Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2` Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2048` Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MongodbResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *MongodbModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name_master", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueString() != state.NeedExternalAddressMaster.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_master", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceCPU.IsNull() || config.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if config.ResourceDisk.IsNull() || config.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if config.ResourceInstances.IsNull() || config.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if config.ResourceMemory.IsNull() || config.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 487: resources_core.FormatInt64(config.ResourceInstances), - 588: resources_core.FormatInt64(config.ResourceMemory), - 589: resources_core.FormatInt64(config.ResourceCPU), - 590: resources_core.FormatInt64(config.ResourceDisk), - 595: resources_core.FormatString(config.ResourceRealm), - 645: resources_core.FormatString(config.NeedExternalAddressMaster), - 646: resources_core.FormatString(config.IpSpaceNameMaster), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 92, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *MongodbResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceCPU.IsNull() || data.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if data.ResourceDisk.IsNull() || data.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if data.ResourceInstances.IsNull() || data.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if data.ResourceMemory.IsNull() || data.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 92, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 487: resources_core.FormatInt64(data.ResourceInstances), - 588: resources_core.FormatInt64(data.ResourceMemory), - 589: resources_core.FormatInt64(data.ResourceCPU), - 590: resources_core.FormatInt64(data.ResourceDisk), - 595: resources_core.FormatString(data.ResourceRealm), - 645: resources_core.FormatString(data.NeedExternalAddressMaster), - 646: resources_core.FormatString(data.IpSpaceNameMaster), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 92, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 92, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 92, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *MongodbResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MongodbModel - var state MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 92, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *MongodbResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *MongodbResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/92_mongodb_user_resource.go b/generated/prod/go/92_mongodb_user_resource.go deleted file mode 100644 index 5a450c4..0000000 --- a/generated/prod/go/92_mongodb_user_resource.go +++ /dev/null @@ -1,357 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mongodb -// Subresource: user - -var _ resource.Resource = &MongodbUserResource{} - -// MongodbUserResource manages a subresource via operations. -type MongodbUserResource struct { - client *core.UniversalClient -} - -type MongodbUserModel struct { - ID types.String `tfsdk:"id"` - MongodbID types.String `tfsdk:"mongodb_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - DbName types.String `tfsdk:"db_name"` - Role types.String `tfsdk:"role"` - Username types.String `tfsdk:"username"` -} - -func NewMongodbUserResource() resource.Resource { - return &MongodbUserResource{} -} - -func (r *MongodbUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mongodb_user" -} - -func (r *MongodbUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "mongodb_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "db_name": schema.StringAttribute{Required: true}, - "role": schema.StringAttribute{Required: true}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MongodbUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan MongodbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.DbName.IsNull() || plan.DbName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "db_name is required.") - return - } - if plan.Role.IsNull() || plan.Role.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "role is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.MongodbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "dbName": resources_core.FormatString(plan.DbName), - "role": resources_core.FormatString(plan.Role), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MongodbUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MongodbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_user" == "" { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.MongodbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "dbName": resources_core.FormatString(plan.DbName), - "role": resources_core.FormatString(plan.Role), - }) - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_user", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MongodbUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.MongodbID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *MongodbUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/93_rabbitmq_resource.go b/generated/prod/go/93_rabbitmq_resource.go deleted file mode 100644 index 7bff3d8..0000000 --- a/generated/prod/go/93_rabbitmq_resource.go +++ /dev/null @@ -1,468 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: rabbitmq -// Service ID: 93 - -var _ resource.Resource = &RabbitmqResource{} -var _ resource.ResourceWithModifyPlan = &RabbitmqResource{} -var _ resource.ResourceWithImportState = &RabbitmqResource{} - -type RabbitmqResource struct { - client *core.UniversalClient -} - -type RabbitmqModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - IpSpaceNameSlave types.String `tfsdk:"ip_space_name_slave"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - NeedExternalAddressSlave types.Bool `tfsdk:"need_external_address_slave"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewRabbitmqResource() resource.Resource { - return &RabbitmqResource{} -} - -func (r *RabbitmqResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_rabbitmq" -} - -func (r *RabbitmqResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"}, - "ip_space_name_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`"}, - "need_external_address_slave": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Выделяет внешний (белый) IP для доступа к slave"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Пример: `2000`"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(30), MarkdownDescription: "Пример: `20`"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1124), MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *RabbitmqResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *RabbitmqModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 116: resources_core.FormatInt64(config.ResourceCPU), - 117: resources_core.FormatInt64(config.ResourceMemory), - 118: resources_core.FormatInt64(config.ResourceDisk), - 119: resources_core.FormatString(config.ResourceRealm), - 224: resources_core.FormatInt64(config.ResourceInstances), - 225: resources_core.FormatBool(config.NeedExternalAddressMaster), - 543: resources_core.FormatString(config.IpSpaceNameMaster), - } - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 93, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *RabbitmqResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 93, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 116: resources_core.FormatInt64(data.ResourceCPU), - 117: resources_core.FormatInt64(data.ResourceMemory), - 118: resources_core.FormatInt64(data.ResourceDisk), - 119: resources_core.FormatString(data.ResourceRealm), - 224: resources_core.FormatInt64(data.ResourceInstances), - 225: resources_core.FormatBool(data.NeedExternalAddressMaster), - 543: resources_core.FormatString(data.IpSpaceNameMaster), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 93, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 93, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RabbitmqResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 93, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *RabbitmqResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan RabbitmqModel - var state RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressSlave.IsNull() != state.NeedExternalAddressSlave.IsNull() || plan.NeedExternalAddressSlave.IsUnknown() != state.NeedExternalAddressSlave.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressSlave.IsNull() && !plan.NeedExternalAddressSlave.IsUnknown() && !state.NeedExternalAddressSlave.IsNull() && !state.NeedExternalAddressSlave.IsUnknown() { - if plan.NeedExternalAddressSlave.ValueBool() != state.NeedExternalAddressSlave.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if plan.IpSpaceNameMaster.ValueString() != state.IpSpaceNameMaster.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameSlave.IsNull() != state.IpSpaceNameSlave.IsNull() || plan.IpSpaceNameSlave.IsUnknown() != state.IpSpaceNameSlave.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameSlave.IsNull() && !plan.IpSpaceNameSlave.IsUnknown() && !state.IpSpaceNameSlave.IsNull() && !state.IpSpaceNameSlave.IsUnknown() { - if plan.IpSpaceNameSlave.ValueString() != state.IpSpaceNameSlave.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 304: resources_core.FormatInt64(plan.ResourceCPU), - 305: resources_core.FormatInt64(plan.ResourceMemory), - 306: resources_core.FormatInt64(plan.ResourceDisk), - 307: resources_core.FormatInt64(plan.ResourceInstances), - 308: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 309: resources_core.FormatBool(plan.NeedExternalAddressSlave), - 545: resources_core.FormatString(plan.IpSpaceNameMaster), - 546: resources_core.FormatString(plan.IpSpaceNameSlave), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 93, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "ipSpaceNameSlave", Field: "IpSpaceNameSlave", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "needExternalAddressSlave", Field: "NeedExternalAddressSlave", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RabbitmqResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *RabbitmqResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *RabbitmqResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/94_lucee_redeploy_action.go b/generated/prod/go/94_lucee_redeploy_action.go deleted file mode 100644 index 8709266..0000000 --- a/generated/prod/go/94_lucee_redeploy_action.go +++ /dev/null @@ -1,141 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: lucee -// Action: redeploy - -var _ resource.Resource = &LuceeRedeployResource{} - -// LuceeRedeployResource triggers a one-time action. -type LuceeRedeployResource struct { - client *core.UniversalClient -} - -type LuceeRedeployModel struct { - ID types.String `tfsdk:"id"` - LuceeID types.String `tfsdk:"lucee_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewLuceeRedeployResource() resource.Resource { - return &LuceeRedeployResource{} -} - -func (r *LuceeRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_lucee_redeploy" -} - -func (r *LuceeRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "lucee_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *LuceeRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan LuceeRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.LuceeID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *LuceeRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state LuceeRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan LuceeRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.LuceeID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *LuceeRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *LuceeRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/94_lucee_resource.go b/generated/prod/go/94_lucee_resource.go deleted file mode 100644 index 24770c5..0000000 --- a/generated/prod/go/94_lucee_resource.go +++ /dev/null @@ -1,475 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: lucee -// Service ID: 94 - -var _ resource.Resource = &LuceeResource{} -var _ resource.ResourceWithModifyPlan = &LuceeResource{} -var _ resource.ResourceWithImportState = &LuceeResource{} - -type LuceeResource struct { - client *core.UniversalClient -} - -type LuceeModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AppVersion types.String `tfsdk:"app_version"` - Domain types.String `tfsdk:"domain"` - GitPath types.String `tfsdk:"git_path"` - HealthPath types.String `tfsdk:"health_path"` - JsonEnv types.String `tfsdk:"json_env"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewLuceeResource() resource.Resource { - return &LuceeResource{} -} - -func (r *LuceeResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_lucee" -} - -func (r *LuceeResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("5.4"), MarkdownDescription: "Версия Lucee"}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/xahys/testlucee"), MarkdownDescription: "Путь до Git, который будет webroot для сайта"}, - "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код"}, - "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{ \"param\": \"value\" }"), MarkdownDescription: "Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *LuceeResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *LuceeModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 103: resources_core.FormatString(config.Domain), - 104: resources_core.FormatString(config.GitPath), - 105: resources_core.FormatString(config.JsonEnv), - 106: resources_core.FormatInt64(config.ResourceCPU), - 107: resources_core.FormatInt64(config.ResourceMemory), - 108: resources_core.FormatString(config.ResourceRealm), - 132: resources_core.FormatString(config.HealthPath), - 139: resources_core.FormatInt64(config.ResourceInstances), - 263: resources_core.FormatString(config.AppVersion), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 94, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *LuceeResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 94, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 103: resources_core.FormatString(data.Domain), - 104: resources_core.FormatString(data.GitPath), - 105: resources_core.FormatString(data.JsonEnv), - 106: resources_core.FormatInt64(data.ResourceCPU), - 107: resources_core.FormatInt64(data.ResourceMemory), - 108: resources_core.FormatString(data.ResourceRealm), - 132: resources_core.FormatString(data.HealthPath), - 139: resources_core.FormatInt64(data.ResourceInstances), - 263: resources_core.FormatString(data.AppVersion), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 94, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 94, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 94, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *LuceeResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan LuceeModel - var state LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() { - if plan.GitPath.ValueString() != state.GitPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.HealthPath.IsNull() != state.HealthPath.IsNull() || plan.HealthPath.IsUnknown() != state.HealthPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() { - if plan.HealthPath.ValueString() != state.HealthPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 133: resources_core.FormatString(plan.GitPath), - 134: resources_core.FormatString(plan.HealthPath), - 135: resources_core.FormatString(plan.JsonEnv), - 136: resources_core.FormatInt64(plan.ResourceCPU), - 137: resources_core.FormatInt64(plan.ResourceMemory), - 138: resources_core.FormatInt64(plan.ResourceInstances), - 264: resources_core.FormatString(plan.AppVersion), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 94, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *LuceeResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *LuceeResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/94_lucee_restart_action.go b/generated/prod/go/94_lucee_restart_action.go deleted file mode 100644 index 9df1530..0000000 --- a/generated/prod/go/94_lucee_restart_action.go +++ /dev/null @@ -1,131 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: lucee -// Action: restart - -var _ resource.Resource = &LuceeRestartResource{} - -// LuceeRestartResource triggers a one-time action. -type LuceeRestartResource struct { - client *core.UniversalClient -} - -type LuceeRestartModel struct { - ID types.String `tfsdk:"id"` - LuceeID types.String `tfsdk:"lucee_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` -} - -func NewLuceeRestartResource() resource.Resource { - return &LuceeRestartResource{} -} - -func (r *LuceeRestartResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_lucee_restart" -} - -func (r *LuceeRestartResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "lucee_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *LuceeRestartResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan LuceeRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.LuceeID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "restart", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *LuceeRestartResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state LuceeRestartModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeRestartResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan LuceeRestartModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.LuceeID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{} - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "restart", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "restart", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *LuceeRestartResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *LuceeRestartResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/95_nodejs_redeploy_action.go b/generated/prod/go/95_nodejs_redeploy_action.go deleted file mode 100644 index 6e63ee5..0000000 --- a/generated/prod/go/95_nodejs_redeploy_action.go +++ /dev/null @@ -1,141 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nodejs -// Action: redeploy - -var _ resource.Resource = &NodejsRedeployResource{} - -// NodejsRedeployResource triggers a one-time action. -type NodejsRedeployResource struct { - client *core.UniversalClient -} - -type NodejsRedeployModel struct { - ID types.String `tfsdk:"id"` - NodejsID types.String `tfsdk:"nodejs_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewNodejsRedeployResource() resource.Resource { - return &NodejsRedeployResource{} -} - -func (r *NodejsRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nodejs_redeploy" -} - -func (r *NodejsRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "nodejs_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NodejsRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan NodejsRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.NodejsID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NodejsRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NodejsRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NodejsRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NodejsRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.NodejsID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NodejsRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *NodejsRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/95_nodejs_resource.go b/generated/prod/go/95_nodejs_resource.go deleted file mode 100644 index c6bc6c6..0000000 --- a/generated/prod/go/95_nodejs_resource.go +++ /dev/null @@ -1,475 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nodejs -// Service ID: 95 - -var _ resource.Resource = &NodejsResource{} -var _ resource.ResourceWithModifyPlan = &NodejsResource{} -var _ resource.ResourceWithImportState = &NodejsResource{} - -type NodejsResource struct { - client *core.UniversalClient -} - -type NodejsModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - AppVersion types.String `tfsdk:"app_version"` - Domain types.String `tfsdk:"domain"` - GitPath types.String `tfsdk:"git_path"` - HealthPath types.String `tfsdk:"health_path"` - JsonEnv types.String `tfsdk:"json_env"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNodejsResource() resource.Resource { - return &NodejsResource{} -} - -func (r *NodejsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nodejs" -} - -func (r *NodejsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "app_version": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("23"), MarkdownDescription: "Версия приложения"}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "git_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("https://github.com/xahys/testnode.git"), MarkdownDescription: "Путь до Git, который будет webroot для сайта"}, - "health_path": schema.StringAttribute{Optional: true, MarkdownDescription: "Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет"}, - "json_env": schema.StringAttribute{Optional: true, MarkdownDescription: "Массив переменных, будут переданы в env приложения"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores). 1000Mili = 1 Ядро"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1024), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NodejsResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NodejsModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 149: resources_core.FormatString(config.Domain), - 150: resources_core.FormatString(config.GitPath), - 151: resources_core.FormatString(config.HealthPath), - 152: resources_core.FormatString(config.JsonEnv), - 153: resources_core.FormatInt64(config.ResourceCPU), - 154: resources_core.FormatInt64(config.ResourceMemory), - 155: resources_core.FormatInt64(config.ResourceInstances), - 156: resources_core.FormatString(config.ResourceRealm), - 270: resources_core.FormatString(config.AppVersion), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 95, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NodejsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 95, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 149: resources_core.FormatString(data.Domain), - 150: resources_core.FormatString(data.GitPath), - 151: resources_core.FormatString(data.HealthPath), - 152: resources_core.FormatString(data.JsonEnv), - 153: resources_core.FormatInt64(data.ResourceCPU), - 154: resources_core.FormatInt64(data.ResourceMemory), - 155: resources_core.FormatInt64(data.ResourceInstances), - 156: resources_core.FormatString(data.ResourceRealm), - 270: resources_core.FormatString(data.AppVersion), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 95, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 95, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NodejsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 95, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NodejsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NodejsModel - var state NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.GitPath.IsNull() != state.GitPath.IsNull() || plan.GitPath.IsUnknown() != state.GitPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.GitPath.IsNull() && !plan.GitPath.IsUnknown() && !state.GitPath.IsNull() && !state.GitPath.IsUnknown() { - if plan.GitPath.ValueString() != state.GitPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.HealthPath.IsNull() != state.HealthPath.IsNull() || plan.HealthPath.IsUnknown() != state.HealthPath.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.HealthPath.IsNull() && !plan.HealthPath.IsUnknown() && !state.HealthPath.IsNull() && !state.HealthPath.IsUnknown() { - if plan.HealthPath.ValueString() != state.HealthPath.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppVersion.IsNull() != state.AppVersion.IsNull() || plan.AppVersion.IsUnknown() != state.AppVersion.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppVersion.IsNull() && !plan.AppVersion.IsUnknown() && !state.AppVersion.IsNull() && !state.AppVersion.IsUnknown() { - if plan.AppVersion.ValueString() != state.AppVersion.ValueString() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 157: resources_core.FormatString(plan.GitPath), - 158: resources_core.FormatString(plan.HealthPath), - 159: resources_core.FormatString(plan.JsonEnv), - 160: resources_core.FormatInt64(plan.ResourceCPU), - 161: resources_core.FormatInt64(plan.ResourceMemory), - 162: resources_core.FormatInt64(plan.ResourceInstances), - 271: resources_core.FormatString(plan.AppVersion), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 95, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "appVersion", Field: "AppVersion", Type: "string"}, - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "gitPath", Field: "GitPath", Type: "string"}, - {Code: "healthPath", Field: "HealthPath", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NodejsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NodejsResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NodejsResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/96_pgadmin_redeploy_action.go b/generated/prod/go/96_pgadmin_redeploy_action.go deleted file mode 100644 index a5c1529..0000000 --- a/generated/prod/go/96_pgadmin_redeploy_action.go +++ /dev/null @@ -1,141 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: pgadmin -// Action: redeploy - -var _ resource.Resource = &PgadminRedeployResource{} - -// PgadminRedeployResource triggers a one-time action. -type PgadminRedeployResource struct { - client *core.UniversalClient -} - -type PgadminRedeployModel struct { - ID types.String `tfsdk:"id"` - PgadminID types.String `tfsdk:"pgadmin_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewPgadminRedeployResource() resource.Resource { - return &PgadminRedeployResource{} -} - -func (r *PgadminRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_pgadmin_redeploy" -} - -func (r *PgadminRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "pgadmin_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PgadminRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PgadminRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.PgadminID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PgadminRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PgadminRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PgadminRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PgadminRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PgadminID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PgadminRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *PgadminRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/96_pgadmin_resource.go b/generated/prod/go/96_pgadmin_resource.go deleted file mode 100644 index 83bc255..0000000 --- a/generated/prod/go/96_pgadmin_resource.go +++ /dev/null @@ -1,449 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: pgadmin -// Service ID: 96 - -var _ resource.Resource = &PgadminResource{} -var _ resource.ResourceWithModifyPlan = &PgadminResource{} -var _ resource.ResourceWithImportState = &PgadminResource{} - -type PgadminResource struct { - client *core.UniversalClient -} - -type PgadminModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - Login types.String `tfsdk:"login"` - Password types.String `tfsdk:"password"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewPgadminResource() resource.Resource { - return &PgadminResource{} -} - -func (r *PgadminResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_pgadmin" -} - -func (r *PgadminResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "login": schema.StringAttribute{Required: true, MarkdownDescription: "Логин для подключения к pgAdmin, в формате email (login@email.net) Не изменяется после создания."}, - "password": schema.StringAttribute{Required: true, MarkdownDescription: "Пароль для подключения к pgAdmin Не изменяется после создания.", Sensitive: true}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота ядра пода (milicores). 1000Mili = 1 Ядро"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(256), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PgadminResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *PgadminModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Login.IsNull() && !plan.Login.IsUnknown() && !state.Login.IsNull() && !state.Login.IsUnknown() { - if plan.Login.ValueString() != state.Login.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить login", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Password.IsNull() && !plan.Password.IsUnknown() && !state.Password.IsNull() && !state.Password.IsUnknown() { - if plan.Password.ValueString() != state.Password.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить password", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Login.IsNull() || config.Login.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "login is required.") - return - } - if config.Password.IsNull() || config.Password.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "password is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 164: resources_core.FormatString(config.Domain), - 165: resources_core.FormatInt64(config.ResourceCPU), - 166: resources_core.FormatInt64(config.ResourceMemory), - 167: resources_core.FormatInt64(config.ResourceDisk), - 169: resources_core.FormatString(config.ResourceRealm), - 170: resources_core.FormatString(config.Login), - 171: resources_core.FormatString(config.Password), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 96, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *PgadminResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Login.IsNull() || data.Login.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "login is required.") - return - } - if data.Password.IsNull() || data.Password.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "password is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 96, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 164: resources_core.FormatString(data.Domain), - 165: resources_core.FormatInt64(data.ResourceCPU), - 166: resources_core.FormatInt64(data.ResourceMemory), - 167: resources_core.FormatInt64(data.ResourceDisk), - 169: resources_core.FormatString(data.ResourceRealm), - 170: resources_core.FormatString(data.Login), - 171: resources_core.FormatString(data.Password), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 96, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 96, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PgadminResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 96, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *PgadminResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PgadminModel - var state PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 172: resources_core.FormatInt64(plan.ResourceCPU), - 173: resources_core.FormatInt64(plan.ResourceMemory), - 174: resources_core.FormatInt64(plan.ResourceDisk), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 96, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PgadminResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *PgadminResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *PgadminResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/97_nodered_resource.go b/generated/prod/go/97_nodered_resource.go deleted file mode 100644 index 0c16b24..0000000 --- a/generated/prod/go/97_nodered_resource.go +++ /dev/null @@ -1,411 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nodered -// Service ID: 97 - -var _ resource.Resource = &NoderedResource{} -var _ resource.ResourceWithModifyPlan = &NoderedResource{} -var _ resource.ResourceWithImportState = &NoderedResource{} - -type NoderedResource struct { - client *core.UniversalClient -} - -type NoderedModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNoderedResource() resource.Resource { - return &NoderedResource{} -} - -func (r *NoderedResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nodered" -} - -func (r *NoderedResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NoderedResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NoderedModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() || config.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 193: resources_core.FormatInt64(config.ResourceCPU), - 194: resources_core.FormatInt64(config.ResourceMemory), - 195: resources_core.FormatInt64(config.ResourceDisk), - 196: resources_core.FormatString(config.ResourceRealm), - 197: resources_core.FormatString(config.Domain), - 323: resources_core.FormatInt64(config.ResourceInstances), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 97, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NoderedResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 97, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 193: resources_core.FormatInt64(data.ResourceCPU), - 194: resources_core.FormatInt64(data.ResourceMemory), - 195: resources_core.FormatInt64(data.ResourceDisk), - 196: resources_core.FormatString(data.ResourceRealm), - 197: resources_core.FormatString(data.Domain), - 323: resources_core.FormatInt64(data.ResourceInstances), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 97, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 97, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NoderedResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 97, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NoderedResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NoderedModel - var state NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 97, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NoderedResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NoderedResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NoderedResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/98_http_redeploy_action.go b/generated/prod/go/98_http_redeploy_action.go deleted file mode 100644 index 4879187..0000000 --- a/generated/prod/go/98_http_redeploy_action.go +++ /dev/null @@ -1,141 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: http -// Action: redeploy - -var _ resource.Resource = &HttpRedeployResource{} - -// HttpRedeployResource triggers a one-time action. -type HttpRedeployResource struct { - client *core.UniversalClient -} - -type HttpRedeployModel struct { - ID types.String `tfsdk:"id"` - HttpID types.String `tfsdk:"http_id"` - RunID types.String `tfsdk:"run_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - ResourceRealm types.String `tfsdk:"resource_realm"` -} - -func NewHttpRedeployResource() resource.Resource { - return &HttpRedeployResource{} -} - -func (r *HttpRedeployResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_http_redeploy" -} - -func (r *HttpRedeployResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "http_id": schema.StringAttribute{Required: true}, - "run_id": schema.StringAttribute{Required: true}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *HttpRedeployResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan HttpRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ResourceRealm.IsNull() || plan.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - instanceUID := strings.TrimSpace(plan.HttpID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "redeploy", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *HttpRedeployResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state HttpRedeployModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HttpRedeployResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan HttpRedeployModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.HttpID.ValueString()) - runID := strings.TrimSpace(plan.RunID.ValueString()) - if instanceUID == "" || runID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра или run_id") - return - } - - params := map[string]string{ - "resourceRealm": resources_core.FormatString(plan.ResourceRealm), - } - - if err := resources_core.RunOperationByCode(ctx, r.client, instanceUID, "redeploy", params); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildActionID(instanceUID, "redeploy", runID)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *HttpRedeployResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - // No-op: removing the resource does not trigger a remote action. -} - -func (r *HttpRedeployResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/98_http_resource.go b/generated/prod/go/98_http_resource.go deleted file mode 100644 index 9f113f1..0000000 --- a/generated/prod/go/98_http_resource.go +++ /dev/null @@ -1,433 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: http -// Service ID: 98 - -var _ resource.Resource = &HttpResource{} -var _ resource.ResourceWithModifyPlan = &HttpResource{} -var _ resource.ResourceWithImportState = &HttpResource{} - -type HttpResource struct { - client *core.UniversalClient -} - -type HttpModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - JsonEnv types.String `tfsdk:"json_env"` - RegistryPath types.String `tfsdk:"registry_path"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewHttpResource() resource.Resource { - return &HttpResource{} -} - -func (r *HttpResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_http" -} - -func (r *HttpResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{"param": "value"}"), MarkdownDescription: "Массив переменных, будут переданы в env приложения Не изменяется после создания."}, - "registry_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("nexus-sa.tst.nubes.ru/docker-nubes/jolt"), MarkdownDescription: "Путь до image, который будет установлен как deployment Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100), MarkdownDescription: "Квота ядра пода (Указывается в mili)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *HttpResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *HttpModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if plan.JsonEnv.ValueString() != state.JsonEnv.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить json_env", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RegistryPath.IsNull() && !plan.RegistryPath.IsUnknown() && !state.RegistryPath.IsNull() && !state.RegistryPath.IsUnknown() { - if plan.RegistryPath.ValueString() != state.RegistryPath.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить registry_path", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - if plan.ResourceRealm.ValueString() != state.ResourceRealm.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() || config.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 212: resources_core.FormatString(config.Domain), - 213: resources_core.FormatInt64(config.ResourceCPU), - 214: resources_core.FormatInt64(config.ResourceMemory), - 215: resources_core.FormatInt64(config.ResourceInstances), - 216: resources_core.FormatString(config.ResourceRealm), - 217: resources_core.FormatString(config.RegistryPath), - 241: resources_core.FormatString(config.JsonEnv), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 98, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *HttpResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 98, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 212: resources_core.FormatString(data.Domain), - 213: resources_core.FormatInt64(data.ResourceCPU), - 214: resources_core.FormatInt64(data.ResourceMemory), - 215: resources_core.FormatInt64(data.ResourceInstances), - 216: resources_core.FormatString(data.ResourceRealm), - 217: resources_core.FormatString(data.RegistryPath), - 241: resources_core.FormatString(data.JsonEnv), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 98, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 98, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HttpResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 98, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *HttpResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan HttpModel - var state HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 218: resources_core.FormatInt64(plan.ResourceCPU), - 219: resources_core.FormatInt64(plan.ResourceMemory), - 220: resources_core.FormatInt64(plan.ResourceInstances), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 98, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HttpResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *HttpResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *HttpResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/99_gitea_resource.go b/generated/prod/go/99_gitea_resource.go deleted file mode 100644 index e6f677b..0000000 --- a/generated/prod/go/99_gitea_resource.go +++ /dev/null @@ -1,482 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: gitea -// Service ID: 99 - -var _ resource.Resource = &GiteaResource{} -var _ resource.ResourceWithModifyPlan = &GiteaResource{} -var _ resource.ResourceWithImportState = &GiteaResource{} - -type GiteaResource struct { - client *core.UniversalClient -} - -type GiteaModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - Domain types.String `tfsdk:"domain"` - PsqlUid types.String `tfsdk:"psql_uid"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewGiteaResource() resource.Resource { - return &GiteaResource{} -} - -func (r *GiteaResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_gitea" -} - -func (r *GiteaResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "psql_uid": schema.StringAttribute{Required: true, MarkdownDescription: "UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *GiteaResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *GiteaModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - planChanged := false - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, plan.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != plan.PsqlUid.ValueString() { - plan.PsqlUid = types.StringValue(resolvedPsqlUid) - planChanged = true - } - } - if planChanged { - resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - if plan.Domain.ValueString() != state.Domain.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - if plan.PsqlUid.ValueString() != state.PsqlUid.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить psql_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.PsqlUid.IsNull() || config.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.PsqlUid.IsNull() && !config.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, config.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != config.PsqlUid.ValueString() { - config.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - params := map[int]string{ - 232: resources_core.FormatInt64(config.ResourceCPU), - 233: resources_core.FormatInt64(config.ResourceMemory), - 234: resources_core.FormatInt64(config.ResourceDisk), - 235: resources_core.FormatInt64(config.ResourceInstances), - 237: resources_core.FormatString(config.Domain), - 238: resources_core.FormatString(config.PsqlUid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 99, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *GiteaResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.PsqlUid.IsNull() || data.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - if !data.PsqlUid.IsNull() && !data.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, data.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedPsqlUid != "" && resolvedPsqlUid != data.PsqlUid.ValueString() { - data.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{2, 50, 81, 82, 88, 89, 94, 95, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 99, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 232: resources_core.FormatInt64(data.ResourceCPU), - 233: resources_core.FormatInt64(data.ResourceMemory), - 234: resources_core.FormatInt64(data.ResourceDisk), - 235: resources_core.FormatInt64(data.ResourceInstances), - 237: resources_core.FormatString(data.Domain), - 238: resources_core.FormatString(data.PsqlUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 99, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 99, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 99, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.PsqlUid.IsNull() && !newState.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, newState.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != newState.PsqlUid.ValueString() { - newState.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *GiteaResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan GiteaModel - var state GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - params := map[int]string{ - 259: resources_core.FormatInt64(plan.ResourceCPU), - 260: resources_core.FormatInt64(plan.ResourceMemory), - 261: resources_core.FormatInt64(plan.ResourceDisk), - 262: resources_core.FormatInt64(plan.ResourceInstances), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 99, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *GiteaResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *GiteaResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/prod/go/registry.go b/generated/prod/go/registry.go deleted file mode 100644 index 183b8c8..0000000 --- a/generated/prod/go/registry.go +++ /dev/null @@ -1,76 +0,0 @@ -package resources_gen - -import "github.com/hashicorp/terraform-plugin-framework/resource" - -// Code generated by tools/gen_v2. DO NOT EDIT. -func AllResources() []func() resource.Resource { - return []func() resource.Resource{ - NewAkhqResource, - NewClickhouseResource, - NewDnsrecordResource, - NewDnszoneResource, - NewDummyResource, - NewFlaskResource, - NewGiteaResource, - NewGiteaComplexResource, - NewHarborResource, - NewHttpResource, - NewK8sSthutrvalClusterResource, - NewK8sZitiControllerResource, - NewKafkaResource, - NewLuceeResource, - NewMariadbResource, - NewMongodbResource, - NewNextcloudResource, - NewNifiResource, - NewNodejsResource, - NewNoderedResource, - NewOpenwhiskResource, - NewPgadminResource, - NewPostgresResource, - NewRabbitmqResource, - NewRedisResource, - NewS3Resource, - NewS3bucketResource, - NewSupersetResource, - NewTemplateResource, - NewTenantResource, - NewValoTenantResource, - NewVappResource, - NewVcComplexResource, - NewVcNsxtResource, - NewVcOrgResource, - NewVcOrgSaasResource, - NewVcVdcResource, - NewVcVdcGroupResource, - NewVcVmResource, - NewVcVmV2Resource, - NewVcVmV3Resource, - NewVcexternalipResource, - NewVmpostgreResource, - NewClickhouseDatabaseResource, - NewClickhouseUserResource, - NewKafkaTopicResource, - NewKafkaUserResource, - NewMongodbUserResource, - NewS3SubUserResource, - NewDummyRedeployResource, - NewHttpRedeployResource, - NewK8sSthutrvalClusterReconcileResource, - NewK8sSthutrvalClusterUpdateSecretsResource, - NewLuceeRedeployResource, - NewLuceeRestartResource, - NewNextcloudRestartResource, - NewNodejsRedeployResource, - NewPgadminRedeployResource, - NewPostgresRecoveryResource, - NewPostgresRestartResource, - NewVcNsxtReconcileResource, - NewVcOrgReconcileResource, - NewVcVdcReconcileResource, - NewVcVdcGroupAddVdcResource, - NewVcVdcGroupReconcileResource, - NewVcVdcGroupRemoveVdcResource, - NewVcVmV3RedeployResource, - } -} diff --git a/generated/prod/json/.gitkeep b/generated/prod/json/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/prod/resources_yaml/100_openwhisk.yaml b/generated/prod/resources_yaml/100_openwhisk.yaml deleted file mode 100644 index 88b1ee9..0000000 --- a/generated/prod/resources_yaml/100_openwhisk.yaml +++ /dev/null @@ -1,54 +0,0 @@ -name: openwhisk -service_id: 100 -service_display_name: Serverless Openwhisk (openwhisk_tenant) -service_short_name: openwhisk -service_man: Добавление и удаления пользователя для работы с Openwhisk -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 41 - kind: instance - action: create - params: - - id: 64 - code: username - data_type: string - required: true - descr: Имя пользователя Openwhisk - - id: 863 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Ресурсная платформа - - name: delete - id: 42 - kind: instance - action: delete - params: - - id: 65 - code: username - data_type: string - required: true - descr: Имя пользователя Openwhisk diff --git a/generated/prod/resources_yaml/110_dnszone.yaml b/generated/prod/resources_yaml/110_dnszone.yaml deleted file mode 100644 index 03d2540..0000000 --- a/generated/prod/resources_yaml/110_dnszone.yaml +++ /dev/null @@ -1,94 +0,0 @@ -name: dnszone -service_id: 110 -service_display_name: DNS зона -service_short_name: dnszone -service_man: '## ![image](https://img.icons8.com/?size=50&id=41400&format=png) Необходимо делегировать зону у регистратора на Авторитетные DNS (Сервера зон)

ns3.ngcloud.ru
``` bash
185.247.187.83
2a10:aa80:0:5::3
```

ns4.ngcloud.ru
``` bash
81.22.46.43
2a10:aa80:0:6::3
```' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 43 - kind: instance - action: create - params: - - id: 66 - code: zoneEmail - data_type: string - required: true - descr: Контактный e-mail - - id: 67 - code: zoneName - data_type: string - required: true - regex: ^([a-z0-9-]+\.)+[a-z0-9-]+$ - descr: Имя зоны - man: Имя зоны - - id: 68 - code: zoneKind - data_type: string - required: true - default: NATIVE - value_list: - - NATIVE - - SLAVE - descr: Тип зоны - - id: 69 - code: zoneMastersForSlave - data_type: string - required: false - descr: Использовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов - - id: 70 - code: zoneTimeToRefresh - data_type: string - required: true - default: "86400" - descr: Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов - - id: 71 - code: zoneTimeToRetry - data_type: string - required: true - default: "7200" - descr: Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов - - id: 72 - code: zoneTimeToExpire - data_type: string - required: true - default: "3600000" - descr: Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным - - id: 73 - code: zoneTimeToLive - data_type: string - required: true - default: "86400" - descr: Время, в течение которого информация будет кешироваться другими DNS-серверами - - id: 284 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: delete - id: 44 - kind: instance - action: delete - params: [] diff --git a/generated/prod/resources_yaml/111_dnsrecord.yaml b/generated/prod/resources_yaml/111_dnsrecord.yaml deleted file mode 100644 index 4efad14..0000000 --- a/generated/prod/resources_yaml/111_dnsrecord.yaml +++ /dev/null @@ -1,100 +0,0 @@ -name: dnsrecord -service_id: 111 -service_display_name: DNS запись -service_short_name: dnsrecord -service_man: Необходима DNS зона, в которой будет создана DNS запись.
Выберите
* Зону в которой будет создана запись
* Тип записи
* Имя записи
* Значение записи -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 45 - kind: instance - action: create - params: - - id: 75 - code: zoneUid - data_type: uuid - required: true - ref_svc_id: 110 - descr: UUID экземпляра услуги DNS-зоны - man: UUID экземпляра услуги DNS-зоны - sort: 10 - - id: 76 - code: recordType - data_type: string - required: true - value_list: - - A - - AAAA - - CNAME - - MX - - PTR - - SOA - - SRV - - TXT - - LUA - - NS - - SSHFP - descr: Тип DNS-записи - man: Тип DNS-записи - sort: 20 - - id: 77 - code: recordName - data_type: string - required: true - unique_scope: parent - descr: Имя записи. Имя зоны в конце проставляется автоматически - man: Имя записи. Имя зоны в конце проставляется автоматически - sort: 30 - - id: 78 - code: recordInput - data_type: string - required: true - descr: Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - man: Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - sort: 40 - is_modifiable: true - - id: 450 - code: recordTTL - data_type: integer > 0 - required: true - default: "3600" - maxvalue: 604800 - minvalue: 30 - descr: Time-to-Leave записи. Раз в какое время запись будет обновлена - sort: 50 - - name: delete - id: 46 - kind: instance - action: delete - params: [] - - name: modify - id: 90 - kind: instance - action: modify - params: - - id: 256 - code: recordInput - data_type: string - required: true - descr: Запись. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP diff --git a/generated/prod/resources_yaml/112_tenant.yaml b/generated/prod/resources_yaml/112_tenant.yaml deleted file mode 100644 index a7ae715..0000000 --- a/generated/prod/resources_yaml/112_tenant.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: tenant -service_id: 112 -service_display_name: Тенант в Grafana -service_short_name: tenant -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 84 - kind: instance - action: create - params: - - id: 239 - code: grafanaOrgName - data_type: string - required: true - regex: ^WZ[\d]+$ - descr: WZ-Код клиента - sort: 10 - - id: 240 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 20 - - name: delete - id: 86 - kind: instance - action: delete - params: [] - - name: modify - id: 87 - kind: instance - action: modify - man: Просто удаляет все текущие датасоурсы и ставит их заново
Полезно, когда нужно "ресетнуть" / "добавить" - params: [] diff --git a/generated/prod/resources_yaml/113_vc_complex.yaml b/generated/prod/resources_yaml/113_vc_complex.yaml deleted file mode 100644 index 038f922..0000000 --- a/generated/prod/resources_yaml/113_vc_complex.yaml +++ /dev/null @@ -1,155 +0,0 @@ -name: vc_complex -service_id: 113 -service_display_name: Быстрый старт -service_short_name: vcComplex -service_man: '# Создает окружение для ВМ.

## Создает сервисы:
**Организация**
**Виртуальный датацентр**
**Каталог**
**Сетевой шлюз периметра**

' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 107 - kind: instance - action: create - params: - - id: 332 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование ресурсной платформы - sort: 1 - - id: 334 - code: vappName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: Имя vApp - sort: 10 - - id: 358 - code: vdcProviderGateway - data_type: string - required: true - default: sandbox-v1cl1-pvdc - descr: Взять из свойств ресурсной платформы.
Путь .vcd.providerVdc - взять KEY

providerGateway Cloud Director. Влияет ресурсы будут предоставлены. Является полем (List<String>) в свойствах рес. платформы ЛК, но сам параметр передаётся только как один String - sort: 200 - - id: 359 - code: virtualServicesCount - required: true - default: "1" - maxvalue: 4 - minvalue: 1 - descr: Кол-во виртуальных сервисов, которые выделяются на AVI. Во избежании коллапса пока выделяется до 4 - sort: 110 - - id: 360 - code: ipSpaceName - data_type: string - required: false - default: internet-ipv4-v1 - descr: Имя ip Space для внешнего IP. Целесообразнее брать самый дешёвый, так как это vip для исходящего трафика. Необходимо задавать если включен needExternalAddressSNAT - sort: 130 - - id: 399 - code: storageConfig - data_type: json - required: true - default: '[{"name": "", "size": 1024}]' - descr: Описывается как массив объектов, где описывается имя политики и её размер - sort: 210 - - id: 400 - code: vdcNetworkPool - data_type: string - required: true - default: nsxt-sandbox-geneve-np - sort: 120 - - id: 401 - code: cpuGuaranteed - data_type: integer > 0 - required: true - default: "20" - value_list: - - "20" - - "50" - - "80" - sort: 20 - - id: 402 - code: memGuaranteed - data_type: integer > 0 - required: true - default: "20" - value_list: - - "20" - - "50" - - "80" - sort: 30 - - id: 403 - code: segroupName - data_type: string - required: false - default: SEGROUP-SANDBOX-CL1-SHARED-01 - descr: Наименование segroup, в котором будут выделяться пулы на AVI - sort: 100 - - id: 404 - code: needExternalAddressSNAT - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Выделяет внешний IP на Edge. Используется для SNAT всего трафика - sort: 40 - - id: 405 - code: needEnableAVI - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает AVI в Cloud Director - sort: 50 - - id: 566 - code: cpuAllocated - data_type: string - required: true - default: "1" - minvalue: 1 - descr: шт - sort: 21 - - id: 567 - code: memAllocated - data_type: integer > 0 - required: true - default: "10" - minvalue: 1 - descr: gb - sort: 31 - - id: 568 - code: vIPCount - data_type: integer > 0 - required: true - default: "0" - maxvalue: 20 - minvalue: 0 - descr: ш - sort: 131 diff --git a/generated/prod/resources_yaml/114_gitea_complex.yaml b/generated/prod/resources_yaml/114_gitea_complex.yaml deleted file mode 100644 index b18075e..0000000 --- a/generated/prod/resources_yaml/114_gitea_complex.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: gitea_complex -service_id: 114 -service_display_name: Комплексная услуга по созданию gitea -service_short_name: GiteaComplex -service_man: Комплексная услуга из ["gittea", "postgres"] -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: [] diff --git a/generated/prod/resources_yaml/115_mariadb.yaml b/generated/prod/resources_yaml/115_mariadb.yaml deleted file mode 100644 index 7fbd969..0000000 --- a/generated/prod/resources_yaml/115_mariadb.yaml +++ /dev/null @@ -1,247 +0,0 @@ -name: mariadb -service_id: 115 -service_display_name: Mariadb -service_short_name: mariadb -service_man: 'Mariadb кластер. Ресурсная платформа: k8s. Автоматизация: k8s operator.
Автоматическое резервное копирование, ручное восстановление.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 138 - kind: instance - action: create - params: - - id: 422 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 10 - - id: 424 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (milicores) - sort: 30 - is_modifiable: true - - id: 425 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1024" - maxvalue: 8192 - minvalue: 1024 - descr: Квота памяти пода (MBytes) - sort: 30 - is_modifiable: true - - id: 426 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 427 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 60 - is_modifiable: true - - id: 428 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к master - sort: 70 - is_modifiable: true - - id: 429 - code: ipSpaceNameMaster - data_type: string - required: false - descr: Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster - sort: 80 - is_modifiable: true - - id: 430 - code: ext_BACKUP_SCHEDULE - data_type: string - required: false - default: 0 * * * * - regex: ^(\*|(\d+|\*\/\d+|\d+(,\d+)*))\s\*\s\*\s\*\s\*$ - descr: Не обязательный. Время запуска бекапа - sort: 90 - is_modifiable: true - - id: 431 - code: appVersion - data_type: string - required: true - default: 9.4.0 - value_list: - - 8.4.0 - - 9.4.0 - descr: Версия MySQL - sort: 100 - - id: 432 - code: autoScale - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги - sort: 310 - is_modifiable: true - - id: 433 - code: autoScalePercentage - data_type: integer > 0 - required: false - default: "10" - value_list: - - "10" - - "15" - - "20" - descr: Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема - sort: 320 - is_modifiable: true - - id: 434 - code: autoScaleTechWindow - data_type: integer >= 0 - required: false - default: "0" - value_list: - - "0" - - "5" - - "12" - - "23" - descr: Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) - sort: 330 - is_modifiable: true - - id: 435 - code: autoScaleQuotaGb - data_type: integer > 0 - required: false - default: "1" - descr: Квота для autoScale - sort: 340 - is_modifiable: true - - id: 459 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - sort: 20 - - name: delete - id: 139 - kind: instance - action: delete - params: - - id: 456 - code: deleteS3Bucket - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Также удалить технический S3 Bucket с бэкапами? - sort: 10 - - name: modify - id: 142 - kind: instance - action: modify - params: - - id: 436 - code: resourceCPU - data_type: integer > 0 - required: false - - id: 437 - code: resourceMemory - data_type: integer > 0 - required: false - - id: 438 - code: resourceInstances - data_type: integer > 0 - required: false - - id: 439 - code: resourceDisk - data_type: integer > 0 - required: false - - id: 440 - code: needExternalAddressMaster - data_type: boolean - required: false - value_list: - - "false" - - "true" - - id: 441 - code: ipSpaceNameMaster - required: false - - id: 442 - code: ext_BACKUP_SCHEDULE - data_type: string - required: false - - id: 443 - code: autoScale - data_type: boolean - required: false - value_list: - - "false" - - "true" - - id: 444 - code: autoScalePercentage - data_type: integer > 0 - required: false - - id: 445 - code: autoScaleTechWindow - data_type: integer >= 0 - required: false - - id: 446 - code: autoScaleQuotaGb - data_type: integer > 0 - required: false - - name: resume - id: 141 - kind: instance - action: resume - params: [] - - name: suspend - id: 140 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/116_kafka.yaml b/generated/prod/resources_yaml/116_kafka.yaml deleted file mode 100644 index d2f3408..0000000 --- a/generated/prod/resources_yaml/116_kafka.yaml +++ /dev/null @@ -1,291 +0,0 @@ -name: kafka -service_id: 116 -service_display_name: ApacheKafka -service_short_name: kafka -service_man: "# Инструкция по развертыванию Apache Kafka через платформу

---
## 1. Общая информация
Брокер сообщений Apache Kafka — это отказоустойчивая распределённая платформа для обмена сообщениями и потоковой обработки данных в реальном времени.
Позволяет надёжно передавать события между сервисами и системами, интегрироваться с внешними решениями и использовать как внутренние, так и защищённые TLS-подключения. Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание кластера
- **delete** — Удаление кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера

- **create_topic** — Создание топика
- **modify_topic** — Модификация топика
- **delete_topic** — Удаление топика

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя


---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса Kafka:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `\tk8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество узлов (брокеров) в кластере Kafka

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore ) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных в гигабайтах. Пример: `20`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`

---
## 4. Выходные параметры
После успешного развертывания ресурса Kafka платформа возвращает ряд параметров.
Ключевым из них является:

**internalConnect**
Это внутренний эндпоинт, который используется для подключения к кластеру Kafka из других сервисов, развернутых внутри той же сети.
Эндпоинт предоставляет доступ к брокерам Kafka по внутренним портам, указанным в конфигурации слушателей.

**externalConnect**
Это внешний эндпоинт (fqdn), который используется для подключения к кластеру Kafka. Для подключения используеться 9093 порт.

Для подключения используются следующие порты:

* 9092 — внутренний нешифрованный доступ (plain).
* 9093 — внутренний и внешний доступ по TLS, с обязательной TLS-аутентификацией.

---
## 5. Дополнительная информация
Для создания топиков, пользователей и управления ими, а также для интеграции с кластерами Kafka используйте соответствующие сервисы и раздел "Облачные сервисы".
---" -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 148 - kind: instance - action: create - params: - - id: 461 - code: resourceInstances - data_type: integer > 0 - required: true - value_list: - - "1" - - "2" - - "3" - - "4" - - "5" - minvalue: 1 - descr: 'Пример: `2`' - sort: 20 - is_modifiable: true - - id: 462 - code: resourceMemory - data_type: integer > 0 - required: true - minvalue: 1000 - descr: 'Пример: `2048`' - sort: 30 - is_modifiable: true - - id: 463 - code: resourceCPU - data_type: integer > 0 - required: true - minvalue: 1000 - descr: 'Пример: `2000`' - sort: 40 - is_modifiable: true - - id: 464 - code: resourceDisk - data_type: integer > 0 - required: true - descr: 'Пример: `20`' - sort: 50 - is_modifiable: true - - id: 465 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`' - sort: 60 - is_modifiable: true - - id: 466 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - sort: 70 - is_modifiable: true - - id: 469 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 5 - - name: create_topic - id: 165 - kind: subresource - action: create - subresource: topic - man: '# Инструкция по управлению топиками Apache Kafka через платформу

## 1. Общая информация

---

Топик — это основная сущность в Apache Kafka, предназначенная для приёма сообщений от продюсеров и передачи их консюмерам.
Платформа позволяет создавать, удалять и изменять параметры топиков без прямого доступа к брокерам, обеспечивая удобное управление через интерфейс или API.

---

## Доступные операции

- **create_topic** — Создание топика
- **modify_topic** — Модификация топика
- **delete_topic** — Удаление топика

---

## 2. Параметры создания топика

Ниже перечислены параметры, которые необходимо указать при создании нового топика:

* **Имя топика**
Название топика.
Должно быть уникальным в пределах кластера.
Пример: `orders-events`.

* **Партиции**
Количество партиций топика.
Рекомендуется выбирать с учётом уровня параллелизма потребителей и предполагаемой нагрузки.
Пример: `6`. Здесь важно рассказать о том как происходит расчет оптимального количества
Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.

* **Реплики**
Количество реплик для каждой партиции.
Обычно равно количеству доступных брокеров или меньше.
Пример: `3`.


---

## 4. Параметры модификации топика

Для уже существующих топиков можно изменять параметры. Все параметры являются опциональными:

* **Имя топика**
Название топика.
Пример: `orders-events`.

* **Партиции**
Новое количество партиций.
Пример: `12`.

* **Реплики**
Новое количество реплик.
Пример: `2`.

---

## 5. Рекомендации

* Планируйте количество партиций с запасом — уменьшение их числа невозможно.
* Количество реплик должно соответствовать требуемому уровню отказоустойчивости, но не превышать количество брокеров.
* Изменение параметров топика в рабочем окружении может временно влиять на производительность. Рекомендуется проводить крупные изменения в периоды минимальной нагрузки.

---' - params: - - id: 523 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`' - sort: 10 - - id: 524 - code: partitions - data_type: integer > 0 - required: true - descr: Число партиций можно увеличить, но уменьшить их нельзя. - - id: 525 - code: replicas - data_type: integer > 0 - required: true - descr: Количество реплик не может привышать количество реплик брокера - sort: 20 - - name: create_user - id: 168 - kind: subresource - action: create - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 530 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - - id: 531 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`' - - id: 532 - code: operations - data_type: string - required: true - descr: 'Пример: `Create, Describe, Read, Write`' - - id: 533 - code: group - data_type: string - required: true - descr: 'Пример: `order-consumers` или `*`' - - id: 534 - code: accessHosts - data_type: string - required: true - descr: 'Пример: `192.168.1.0/24` или `*`' - - name: delete - id: 149 - kind: instance - action: delete - params: [] - - name: delete_topic - id: 167 - kind: subresource - action: delete - subresource: topic - params: - - id: 529 - code: nameTopic - data_type: string - required: true - descr: Необходимо выбрать топик, который необходимо удалить - - name: delete_user - id: 170 - kind: subresource - action: delete - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 540 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - - name: modify - id: 162 - kind: instance - action: modify - params: - - id: 501 - code: resourceInstances - data_type: integer > 0 - required: false - value_list: - - "1" - - "2" - - "3" - - "4" - - "5" - descr: 'Пример: `2`' - - id: 502 - code: resourceMemory - data_type: integer > 0 - required: false - minvalue: 1000 - descr: 'Пример: `2048`' - - id: 503 - code: resourceCPU - required: false - minvalue: 1000 - descr: 'Пример: `2000`' - - id: 504 - code: resourceDisk - data_type: integer > 0 - required: false - descr: 'Пример: `20`' - - id: 505 - code: needExternalAddressMaster - data_type: boolean - required: false - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`' - - id: 506 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - - name: modify_topic - id: 166 - kind: subresource - action: modify - subresource: topic - man: '# Инструкция по управлению топиками Apache Kafka через платформу

## 1. Общая информация

---

Топик — это основная сущность в Apache Kafka, предназначенная для приёма сообщений от продюсеров и передачи их консюмерам.
Платформа позволяет создавать, удалять и изменять параметры топиков без прямого доступа к брокерам, обеспечивая удобное управление через интерфейс или API.

---

## Доступные операции

- **create_topic** — Создание топика
- **modify_topic** — Модификация топика
- **delete_topic** — Удаление топика

---

## 2. Параметры создания топика

Ниже перечислены параметры, которые необходимо указать при создании нового топика:

* **Имя топика**
Название топика.
Должно быть уникальным в пределах кластера.
Пример: `orders-events`.

* **Партиции**
Количество партиций топика.
Рекомендуется выбирать с учётом уровня параллелизма потребителей и предполагаемой нагрузки.
Пример: `6`. Здесь важно рассказать о том как происходит расчет оптимального количества
Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.

* **Реплики**
Количество реплик для каждой партиции.
Обычно равно количеству доступных брокеров или меньше.
Пример: `3`.


---

## 4. Параметры модификации топика

Для уже существующих топиков можно изменять параметры. Все параметры являются опциональными:

* **Имя топика**
Название топика.
Пример: `orders-events`.

* **Партиции**
Новое количество партиций.
Пример: `12`.

* **Реплики**
Новое количество реплик.
Пример: `2`.

---

## 5. Рекомендации

* Планируйте количество партиций с запасом — уменьшение их числа невозможно.
* Количество реплик должно соответствовать требуемому уровню отказоустойчивости, но не превышать количество брокеров.
* Изменение параметров топика в рабочем окружении может временно влиять на производительность. Рекомендуется проводить крупные изменения в периоды минимальной нагрузки.

---' - params: - - id: 526 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`' - sort: 10 - - id: 527 - code: partitions - required: false - descr: Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - sort: 30 - - id: 528 - code: replicas - required: false - descr: Количество партиций ≤ (число брокеров). Пример `2` - sort: 20 - - name: modify_user - id: 169 - kind: subresource - action: modify - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 535 - code: nameTopic - data_type: string - required: false - descr: 'Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`' - - id: 536 - code: operations - data_type: string - required: false - descr: 'Пример: `Create, Describe, Read, Write`' - - id: 537 - code: group - data_type: string - required: false - descr: 'Пример: `order-consumers` или `*`' - - id: 538 - code: accessHosts - data_type: string - required: false - descr: 'Пример: `192.168.1.0/24` или `*`' - - id: 539 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - sort: 10 - - name: resume - id: 161 - kind: instance - action: resume - params: [] - - name: suspend - id: 160 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/117_nifi.yaml b/generated/prod/resources_yaml/117_nifi.yaml deleted file mode 100644 index 39c49bd..0000000 --- a/generated/prod/resources_yaml/117_nifi.yaml +++ /dev/null @@ -1,81 +0,0 @@ -name: nifi -service_id: 117 -service_display_name: Nifi -service_short_name: nifi -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 150 - kind: instance - action: create - params: - - id: 471 - code: kafkaUid - data_type: uuid - required: true - ref_svc_id: 116 - descr: Выбрать кластер из списка - sort: 10 - - id: 472 - code: partitions - data_type: integer > 0 - required: true - descr: Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - man: 'Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.' - sort: 30 - is_modifiable: true - - id: 473 - code: replicas - data_type: integer > 0 - required: true - descr: Количество партиций ≤ (число брокеров). Пример `2` - sort: 40 - is_modifiable: true - - id: 474 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`' - sort: 20 - - name: delete - id: 151 - kind: instance - action: delete - params: [] - - name: modify - id: 154 - kind: instance - action: modify - params: - - id: 477 - code: partitions - data_type: integer > 0 - required: false - descr: Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - man: 'Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.' - - id: 478 - code: replicas - data_type: integer > 0 - required: false - descr: Количество партиций ≤ (число брокеров). Пример `2` diff --git a/generated/prod/resources_yaml/119_akhq.yaml b/generated/prod/resources_yaml/119_akhq.yaml deleted file mode 100644 index 7339976..0000000 --- a/generated/prod/resources_yaml/119_akhq.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: akhq -service_id: 119 -service_display_name: Akhq -service_short_name: Akhq -service_man: '# Инструкция по развертыванию Apache Kafka через платформу

---
## 1. Общая информация
AKHQ — это веб-интерфейс для работы с кластерами Apache Kafka.
Позволяет просматривать топики, consumer group''ы, сообщения, ACL, схему безопасности, состояние брокеров и метаданные.
Поддерживает работу с несколькими кластерами Kafka одновременно, включая внутренние и внешние (TLS) подключения.

## Доступные операции
- **create** — Создание ресурса AKHQ
- **suspend** — Остановка ресурса
- **resume** — Возобновление работы ресурса
- **modify** — Модификация настроек
- **delete** — Удаление ресурса

---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса Kafka:

* **Кластер Kafka к которому нужно настроить подключение**
Для использования AKHQ необходимо предварительно развернуть сервис Kafka. Пример: `kafka-external`.

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество узлов для работы Akhq. Пример `2`

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `512`

* **Квота (millicore ) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `500`

* **Имя домена:**
Dns Имя по которому будет происходить обращение к сервису. Указать необходимо уникальное имя до . ( то есть если необходимо получить dns ui) Пример: `kafka-external`

---
## 4. Выходные параметры
После успешного развертывания ресурса Kafka платформа возвращает ряд параметров.
Ключевым из них является:

**connectionUrl**
Это полное доменное имя (FQDN), по которому будет доступен интерфейс AKHQ. После развёртывания подождите несколько минут — UI станет доступен по HTTPS, как только все сервисы полностью запустятся.

**Учетные данные**
Здесь представлены поля для ввода логина и пароля, с помощью которых вы сможете авторизоваться в сервисе.

---
## 5. Дополнительная информация
Учётные записи, созданные для работы с AKHQ, предоставляют доступ только для просмотра данных. Для управления Kafka, пожалуйста, используйте возможности личного кабинета.
---' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 175 - kind: instance - action: create - params: - - id: 550 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 551 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - minvalue: 512 - descr: 'Пример: `1024`' - sort: 20 - - id: 552 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - minvalue: 500 - descr: 'Пример: `1000`' - sort: 30 - - id: 553 - code: domain - data_type: string - required: true - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 40 - - id: 554 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - minvalue: 1 - sort: 11 - - id: 555 - code: kafkaUid - data_type: uuid - required: true - ref_svc_id: 116 - descr: Выбрать кластер из списка - sort: 5 - is_modifiable: true - - name: delete - id: 176 - kind: instance - action: delete - params: [] - - name: modify - id: 180 - kind: instance - action: modify - params: - - id: 565 - code: kafkaUid - data_type: uuid - required: true - ref_svc_id: 116 - descr: Выбрать кластер из списка - - name: resume - id: 178 - kind: instance - action: resume - params: [] - - name: suspend - id: 177 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/120_clickhouse.yaml b/generated/prod/resources_yaml/120_clickhouse.yaml deleted file mode 100644 index efae3cf..0000000 --- a/generated/prod/resources_yaml/120_clickhouse.yaml +++ /dev/null @@ -1,417 +0,0 @@ -name: clickhouse -service_id: 120 -service_display_name: ClickHouse -service_short_name: clickhouse -service_man: '# Инструкция по управлению кластерами и пользователями ClickHouse

---

## Общая информация

ClickHouse — это колоночная система управления базами данных, предназначенная для обработки аналитических запросов в реальном времени. Платформа позволяет создавать, удалять, приостанавливать и возобновлять кластеры ClickHouse, а также управлять базами данных и пользователями.

Кластер создаётся через оператор Altinity (`https://github.com/Altinity/clickhouse-operator`) в ресурсной платформе типа `k8s`

Кластеры могут создаваться шардированными с произвольным количеством реплик. Для обеспечения отказоустойчивости и координации обязательно включение параметра `Создать ClickHouse-Keeper`.

Кластера создаются с обязательным бекапом. Для этого необходимо предварительно создать услугу `S3 Object Storage`.
---

## Доступные операции

* **create** — Создание кластера
* **delete** — Удаление кластера
* **suspend** — Приостановка работы кластера
* **resume** — Возобновление работы кластера
* **create_database** — Создание базы данных
* **delete_database** — Удаление базы данных
* **create_user** — Создание пользователя и настройка прав доступа к базе данных
* **delete_user** — Удаление пользователя

## Процесс создания и первого подключения

1. Выполнить операцию `create` - будет создан кластер
2. Выполнить операцию `create_database` - будет создана база данных
3. Выполнить операцию `create_user` - будет создан пользователь (выбрать доступ подключения к БД, созданной в п.2)

## Примеры подключения

### Подключение через HTTP-интерфейс

```bash
# Проверка доступности кластера
curl "http://<username>:<password>@<host>:8123/" -d "SELECT 1"

# Выполнение запроса
curl "http://<username>:<password>@<host>:8123/" -d "SHOW DATABASES"
```

## Простые кейсы
*Создать БД и обычной таблицы*
```clickhouse
CREATE TABLE database.table
(
id UInt64,
value String
)
ENGINE = MergeTree()
ORDER BY id;

INSERT INTO database.table SELECT number, toString(number) FROM numbers(10000000);

SELECT count() FROM database.table;
```
Базы и таблицы не реплицируются без специального ключа (`ON CLUSTER ''clickhousek8s''`)
В случае создания в стиле, описанным выше, необходимо будет выполнять действия на всех шардах/репликах


*Создание БД и шардированной таблицы*
```clickhouse
CREATE TABLE database.localUsers
(
id UInt64,
value String
)
ENGINE = MergeTree()
ORDER BY id;

CREATE TABLE database.shardedTable
AS localUsers
ENGINE = Distributed(''clickhousek8s'', ''database'', ''localUsers'', id);

INSERT INTO shardedTable SELECT number, toString(number) FROM numbers(10000000);

SELECT count() FROM shardedTable;
```
Важный момент - в данном примере таблицы придётся также выполнять на всех нодах ClickHouse

*Создание реплицируемой и шардированной таблицы*
```clickhouse
CREATE TABLE IF NOT EXISTS database.localUsers ON cluster ''clickhousek8s''
(
user_id UInt64,
name String,
email String
)
ENGINE = ReplicatedMergeTree(
''/clickhouse/tables/{shard}/localUsers'',
''{replica}''
)
ORDER BY user_id;

CREATE TABLE IF NOT EXISTS database.users ON cluster ''clickhousek8s''
AS database.localUsers
ENGINE = Distributed(''clickhousek8s'', ''database'', ''localUsers'', rand());

INSERT INTO database.users VALUES (1, ''Alice'', ''alice@example.com'');
INSERT INTO database.users VALUES (2, ''Bob'', ''bob@example.com'');
INSERT INTO database.users VALUES (3, ''Charlie'', ''charlie@example.com'');
INSERT INTO database.users VALUES (4, ''David'', ''david@example.com'');
INSERT INTO database.users VALUES (5, ''Gosha'', ''gosha@example.com'');
INSERT INTO database.users VALUES (6, ''Eve'', ''eve@example.com'');
INSERT INTO database.users VALUES (7, ''Frank'', ''frank@example.com'');
INSERT INTO database.users VALUES (8, ''Grace'', ''grace@example.com'');
INSERT INTO database.users VALUES (9, ''Hannah'', ''hannah@example.com'');
INSERT INTO database.users VALUES (10, ''Ivan'', ''ivan@example.com'');

SELECT * FROM database.localUsers;
SELECT * FROM database.users;

SELECT COUNT(*) AS total_users FROM database.users;
SELECT COUNT(*) AS total_users_local FROM database.localUsers;
```' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 181 - kind: instance - action: create - man: Операция создания кластера ClickHouse

Для подключения к кластеру также необходимо создать базу данных через операцию `create_database` и создание пользователя через операцию `create_user` - params: - - id: 572 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Кластер Kubernetes в котором будет развёрнуто приложение - man: Выбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы - sort: 10 - - id: 573 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - man: '**Если список не отображается**
перейдите в раздел `S3 Object Storage`
операция `create`' - sort: 20 - - id: 574 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `3`' - man: '**Для синхронизации данных между репликами** необходимо включить `Создать ClickHouse-Keeper`' - sort: 30 - is_modifiable: true - - id: 575 - code: resourceInstancesShards - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - man: '**Шард** - это часть данных, разделенная на разные узлы (серверы) для горизонтального масштабирования и обработки больших объемов информации.
**Реплика** - это точная копия данных внутри одного шарда' - sort: 40 - is_modifiable: true - - id: 576 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 8000 - minvalue: 1000 - descr: 'Пример: `1000`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 50 - is_modifiable: true - - id: 577 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1536" - maxvalue: 8192 - minvalue: 1536 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 60 - is_modifiable: true - - id: 578 - code: appVersion - data_type: string - required: true - default: "25.10" - value_list: - - "25.10" - descr: Версия `clickhouse-server` - sort: 70 - is_modifiable: true - - id: 579 - code: resourceDisk - data_type: integer > 0 - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `100`' - man: Указывается в Gigabytes - sort: 80 - is_modifiable: true - - id: 580 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Позволяет подключиться извне к ClickHouse - man: Для выделения IP также необходимо указать имя Ip-space.
Его можно получить из свойств ресурсной платформы - sort: 90 - is_modifiable: true - - id: 581 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - man: Имя ipSpace для публикации внешнего адреса

Не может быть пустым, если включен `Выделение белого ip для master ноды` - sort: 100 - is_modifiable: true - - id: 582 - code: needCreateKeeper - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Необходим для кластеризации ClickHouse - man: Аналог `Zookeeper`, представленный от ClickHouse - sort: 200 - is_modifiable: true - - id: 583 - code: resourceCPUKeeper - data_type: integer > 0 - required: true - default: "50" - maxvalue: 8000 - minvalue: 50 - descr: 'Пример: `100`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 210 - is_modifiable: true - - id: 584 - code: resourceMemoryKeeper - data_type: integer > 0 - required: true - default: "152" - maxvalue: 8192 - minvalue: 152 - descr: 'Пример: `256`' - man: Указывается в Megabytes - sort: 220 - is_modifiable: true - - id: 585 - code: resourceInstancesKeeper - data_type: integer > 0 - required: true - default: "1" - value_list: - - "1" - - "3" - maxvalue: 3 - minvalue: 1 - descr: 'Пример: `1`' - man: Для **теста** - 1 нода.
Для **продуктива** - 3 ноды - sort: 230 - is_modifiable: true - - id: 586 - code: ext_BACKUP_SCHEDULE - data_type: string - required: true - default: 0 0 * * * - regex: ^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$ - descr: Принимает формат `CRON` - sort: 500 - is_modifiable: true - - id: 587 - code: ext_BACKUP_NUM_TO_RETAIN - data_type: integer > 0 - required: true - default: "7" - maxvalue: 60 - minvalue: 3 - descr: 'Пример: `7`' - man: Кол-во **полных** резервных копий
Кол-во инкрементов - неограничено

Полная резервная копия выполняется раз в неделю
*Если изначально полной резервной копии нет* выполняется полный бекап
В остальные дни по крону выполняются **инкременты** - sort: 510 - is_modifiable: true - - name: create_database - id: 186 - kind: subresource - action: create - subresource: database - man: База данных создаётся на всех репликах кластера ClickHouse - params: - - id: 600 - code: databaseName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: 'Пример: `db01`' - sort: 10 - - name: create_user - id: 185 - kind: subresource - action: create - subresource: user - params: - - id: 596 - code: username - data_type: string - required: true - regex: ^(?![0-9_])[a-zA-Z_][a-zA-Z0-9_]{0,62}$ - maxlength: 62 - minlength: 2 - descr: 'Пример: `myusername`' - sort: 10 - - id: 598 - code: databaseName - data_type: json - required: true - default: '["database"]' - descr: Необходимо указать массив существующих баз - man: Если базы не существует - при выполнении операции вернётся ошибка - sort: 30 - - id: 599 - code: accessHosts - data_type: string - required: true - default: ::/0 - descr: 'Пример: `::/0`' - sort: 40 - - name: delete - id: 184 - kind: instance - action: delete - man: Удаление возможно только после остановки сервиса через операцию `suspend`
После выполнения операции необходимо выждать определенное кол-во времени - params: [] - - name: delete_database - id: 188 - kind: subresource - action: delete - subresource: database - man: Необратимое действие!!!
Трижды подумай, заблокируй телефон тимлида и не выполняй это действие - params: - - id: 602 - code: databaseName - data_type: string - required: true - descr: ВСЕ ДАННЫЕ ВНУТРИ БД БУДУТ УДАЛЕНЫ - - name: delete_user - id: 187 - kind: subresource - action: delete - subresource: user - params: - - id: 601 - code: username - required: true - descr: Имя пользователя, созданное через операцию `create_user` - - name: modify - id: 189 - kind: instance - action: modify - params: - - id: 603 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `3`' - man: '**Для синхронизации данных между репликами** необходимо включить `Создать ClickHouse-Keeper`' - sort: 10 - - id: 604 - code: resourceInstancesShards - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - man: '**Шард** - это часть данных, разделенная на разные узлы (серверы) для горизонтального масштабирования и обработки больших объемов информации.
**Реплика** - это точная копия данных внутри одного шарда' - sort: 20 - - id: 605 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 8000 - minvalue: 1000 - descr: 'Пример: `1000`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 30 - - id: 606 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 1536 - descr: 'Пример: `2048`' - man: Указывается в Megabytes - sort: 40 - - id: 607 - code: appVersion - data_type: string - required: true - default: "25.10" - descr: Версия `clickhouse-server` - sort: 50 - - id: 608 - code: resourceDisk - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `100`' - man: Указывается в Gigabytes
**Нельзя** выставлять меньше текущего значения - sort: 60 - - id: 609 - code: needExternalAddressMaster - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Позволяет подключиться извне к ClickHouse - man: Для выделения IP также необходимо указать имя Ip-space.
Его можно получить из свойств ресурсной платформы - sort: 70 - - id: 610 - code: ipSpaceNameMaster - data_type: string - required: true - descr: 'Пример: `internet-no-antiddos-v1`' - man: Имя ipSpace для публикации внешнего адреса

Не может быть пустым, если включен `Выделение белого ip для master ноды` - sort: 80 - - id: 611 - code: needCreateKeeper - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Необходим для кластеризации ClickHouse - man: Аналог `Zookeeper`, представленный от ClickHouse - sort: 200 - - id: 612 - code: resourceCPUKeeper - data_type: integer > 0 - required: true - maxvalue: 8000 - minvalue: 50 - descr: 'Пример: `100`' - man: Указывается в Milicores
`1000` Mili == `1` Ядро - sort: 210 - - id: 613 - code: resourceMemoryKeeper - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 152 - descr: 'Пример: `256`' - man: Указывается в Megabytes - sort: 220 - - id: 614 - code: resourceInstancesKeeper - data_type: integer > 0 - required: true - value_list: - - "1" - - "3" - maxvalue: 3 - minvalue: 1 - descr: 'Пример: `1`' - man: Для **теста** - 1 нода.
Для **продуктива** - 3 ноды - sort: 230 - - id: 615 - code: ext_BACKUP_SCHEDULE - data_type: string - required: true - default: 0 0 * * * - regex: ^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$ - descr: Принимает формат `CRON` - sort: 500 - - id: 616 - code: ext_BACKUP_NUM_TO_RETAIN - data_type: integer > 0 - required: true - maxvalue: 60 - minvalue: 3 - descr: 'Пример: `7`' - man: Кол-во **полных** резервных копий
Кол-во инкрементов - неограничено

Полная резервная копия выполняется раз в неделю
*Если изначально полной резервной копии нет* выполняется полный бекап
В остальные дни по крону выполняются **инкременты** - sort: 510 - - name: resume - id: 183 - kind: instance - action: resume - params: [] - - name: suspend - id: 182 - kind: instance - action: suspend - man: Операция приводит к удалению всех подов
Persistent Volume остаются нетронутыми - params: [] diff --git a/generated/prod/resources_yaml/12_s3.yaml b/generated/prod/resources_yaml/12_s3.yaml deleted file mode 100644 index 6b7e343..0000000 --- a/generated/prod/resources_yaml/12_s3.yaml +++ /dev/null @@ -1,121 +0,0 @@ -name: s3 -service_id: 12 -service_display_name: S3 Object Storage -service_short_name: s3 -service_man: Руководство доступно по ссылке:
https://docs.s3.msk-1.ngcloud.ru/s3/s3.description.html -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 1 - kind: instance - action: create - params: - - id: 163 - code: resourceRealm - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: кластер S3 для подключения - sort: 20 - - id: 320 - code: displayName - data_type: string - required: true - descr: Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента - sort: 10 - - name: create_sub_user - id: 6 - kind: subresource - action: create - subresource: sub_user - params: - - id: 60 - code: subUserName - data_type: string - required: true - - id: 61 - code: subUserAccess - data_type: string - required: true - value_list: - - read - - write - - readwrite - - full - - name: delete - id: 5 - kind: instance - action: delete - params: [] - - name: delete_sub_user - id: 7 - kind: subresource - action: delete - subresource: sub_user - params: - - id: 63 - code: subUserName - data_type: string - required: true - descr: subUserName. По идее услуга уже создана - должен передаваться из ЛК - - name: modify - id: 4 - kind: instance - action: modify - man: При первичном вызове операции услуга Trial прекращает действие - params: - - id: 50 - code: maxSizeGbPerUser - data_type: integer - required: false - maxvalue: 50000 - minvalue: -1 - descr: maxSizeGb. Передаём руками - man: maxSizeGb. Передаём руками - - id: 51 - code: maxObjectsPerBucket - data_type: integer > 0 - required: false - maxvalue: 1e+07 - minvalue: 1 - descr: Квота на бакет. Кол-во объектов. Передаём руками - man: Квота на бакет. Кол-во объектов. Передаём руками - - id: 52 - code: maxBucketsPerUser - data_type: integer > 0 - required: false - maxvalue: 1000 - minvalue: 1 - descr: Квота на пользователя. Количество бакетов пользователя. Передаём руками - man: Квота на пользователя. Количество бакетов пользователя. Передаём руками - - name: resume - id: 3 - kind: instance - action: resume - params: [] - - name: suspend - id: 2 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/13_s3bucket.yaml b/generated/prod/resources_yaml/13_s3bucket.yaml deleted file mode 100644 index 68e506c..0000000 --- a/generated/prod/resources_yaml/13_s3bucket.yaml +++ /dev/null @@ -1,90 +0,0 @@ -name: s3bucket -service_id: 13 -service_display_name: S3 бакет -service_short_name: s3bucket -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 51 - kind: instance - action: create - params: - - id: 124 - code: s3UserUid - data_type: uuid - required: true - ref_svc_id: 12 - descr: UID Корневой услуги S3. На основе него будет создан бакет. - - id: 125 - code: bucketName - data_type: string - required: true - descr: Имя бакета s3 - - id: 126 - code: maxSize - required: true - default: "-1" - descr: Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes - man: Максимальный размер бакета s3. Если поставить 0, будет безлимит. Размер указывается в Bytes - - id: 127 - code: readAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. - - id: 128 - code: listAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. - - id: 129 - code: corsAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS - - id: 130 - code: placement - data_type: string - required: true - default: HOT - value_list: - - HOT - - COLD - descr: Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения - - name: delete - id: 52 - kind: instance - action: delete - params: [] diff --git a/generated/prod/resources_yaml/149_valo_tenant.yaml b/generated/prod/resources_yaml/149_valo_tenant.yaml deleted file mode 100644 index ddb0afb..0000000 --- a/generated/prod/resources_yaml/149_valo_tenant.yaml +++ /dev/null @@ -1,98 +0,0 @@ -name: valo_tenant -service_id: 149 -service_display_name: VALO Cloud -service_short_name: valoTenant -service_man: '# Инструкция по развертыванию Тенант Valo через платформу

## 1. Общая информация
Тенант Valo — логический изолированный экземпляр сервиса VALO Cloud, предоставляющий защищённое облачное хранилище, синхронизацию данных и доступ к документам с различных устройств. При создании тенант автоматически разворачивается в тестовом режиме сроком на 2 месяца. Перевод в промышленную эксплуатацию выполняется отдельной операцией.

### Доступные операции

* **create** — создание нового тенанта в тестовом режиме сроком на 2 месяца.
* **modify** — изменение настроек тенанта, включая перевод из ТЕСТ в ПРОД.
* **suspend** — выключение (приостановка работы) тенанта.
* **resume** — включение ранее приостановленного тенанта.
* **delete** — удаление тенанта; доступно только после выполнения операции suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создан тенант.
Пример значения: `valo.ngcloud.ru`.

### DNS-Префикс
Описание: Будет добавлено в зону valo.ngcloud.ru
Пример значения: `mysimpledomain`.

### Параметры хранилища
Описание: Сколько места будет выделено под использование в тенанте. Данные хранятся в S3. Размер указывается в Gigabytes
Пример значения: `10`.

### Настройки тенанта
Описание: Ряд конфигурации Valo-тенанта, такие как настройки пользователя и доступного функционала
Пример значения: `опционально в рамках настройки`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
Достаточно развернуть тенант в ТЕСТ. Срок предоставляется в 2 месяца. По истечению срока тенант автоматически переводится в `suspend` на стороне ресурсной платформы

### Промышленное окружение
Для разблокировки используйте операцию `modify`

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Статус тенанта
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация
Тенант всегда создаётся в режиме ТЕСТ и не может быть сразу переведён в ПРОД без операции modify.
Удаление тенанта возможно только после его выключения с помощью операции suspend.
Срок тестового режима составляет 2 месяца с момента создания.
Операции suspend и resume используются для временного управления доступностью сервиса без потери конфигурации.
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 202 - kind: instance - action: create - params: - - id: 655 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - sort: 10 - - id: 656 - code: domain - data_type: string - required: true - regex: ^[a-z0-9](?:[a-z0-9-]{3,61}[a-z0-9])?$ - maxlength: 61 - minlength: 3 - descr: Будет добавлено в зону valo.ngcloud.ru - sort: 20 - - id: 657 - code: valoOptions - data_type: map-fixed - required: true - default: '{}' - sort: 40 - is_modifiable: true - - id: 658 - code: s3Storage - data_type: integer > 0 - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: Параметр указывается в `Gb` - man: Данные хранятся в отдельном экземпляре S3 - sort: 30 - is_modifiable: true - - name: delete - id: 206 - kind: instance - action: delete - params: [] - - name: modify - id: 203 - kind: instance - action: modify - params: - - id: 659 - code: valoOptions - data_type: map-fixed - required: true - sort: 10 - - id: 660 - code: s3Storage - data_type: integer > 0 - required: true - descr: Параметр указывается в `Gb` - man: Данные хранятся в отдельном экземпляре S3 - sort: 20 - - name: resume - id: 205 - kind: instance - action: resume - params: [] - - name: suspend - id: 204 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/150_k8s_sthutrval_cluster.yaml b/generated/prod/resources_yaml/150_k8s_sthutrval_cluster.yaml deleted file mode 100644 index 3afa81e..0000000 --- a/generated/prod/resources_yaml/150_k8s_sthutrval_cluster.yaml +++ /dev/null @@ -1,227 +0,0 @@ -name: k8s_sthutrval_cluster -service_id: 150 -service_display_name: Kubernetes кластер Штурвал -service_short_name: k8sSthutrvalCluster -service_man: Перед разворачиванием убедиться, что в облаке есть 2 свободных невыделенных IP в пуле -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 108 - kind: instance - action: create - params: - - id: 344 - code: nsxtUid - data_type: uuid - required: true - ref_svc_id: 22 - descr: InstanceUid nsxt. Nsxt должен быть создан - sort: 10 - - id: 345 - code: clusterName - data_type: string - required: true - default: example1 - regex: (?=^.{1,63}$)^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ - unique_scope: provider - descr: Наименование кластера Kubernetes. Имя будет использоваться в fqdn (svc.$CLUSTER_NAME) - sort: 25 - - id: 346 - code: controlPlaneSizingPolicy - data_type: string - required: true - descr: Настройка Control Plane. CPU (шт) / MEM (gb).
Наверное, должна подтягиваться из свойств ресурсной платформы - sort: 30 - depends_on: vdcUid - - id: 347 - code: controlPlaneSizingDisk - data_type: integer > 0 - required: true - default: "30" - maxvalue: 999 - minvalue: 20 - descr: Настройка Control Plane. Disk (Gb) - sort: 40 - is_modifiable: true - - id: 348 - code: controlPlaneCount - data_type: integer > 0 - required: true - default: "1" - maxvalue: 9 - minvalue: 1 - sort: 50 - is_modifiable: true - - id: 349 - code: workersSizingPolicy - data_type: string - required: true - descr: Настройка workers. CPU (шт) / MEM (gb) - sort: 60 - depends_on: vdcUid - - id: 350 - code: workersSizingDisk - data_type: integer > 0 - required: true - default: "40" - maxvalue: 999 - minvalue: 20 - descr: Настройка workers. Disk (Gb) - sort: 70 - is_modifiable: true - - id: 351 - code: workersCount - data_type: integer > 0 - required: true - default: "2" - maxvalue: 99 - minvalue: 1 - descr: Настройка workers. Кол-во нод - sort: 80 - is_modifiable: true - - id: 352 - code: appVersion - data_type: string - required: true - default: 2.12.1 - value_list: - - 2.12.1 - - 2.11.0 - descr: Версия Штурвал (не является версией Kubernetes) - sort: 90 - is_modifiable: true - - id: 353 - code: needExternalAddressAPI - data_type: boolean - required: true - default: "true" - value_list: - - "true" - descr: Выделяет внешний IP для доступа к kubernetes API. Пока нельзя выставить false - sort: 100 - - id: 354 - code: accessIpListAPI - data_type: json - required: true - default: '[]' - descr: Access IP List для подключения к Kubernetes API. Указывается массив. Если передан пустой массив, доступ выделяется всем - sort: 110 - is_modifiable: true - - id: 355 - code: needExternalAddressIngress - data_type: boolean - required: true - default: "true" - value_list: - - "true" - descr: Выделяет внешний IP для доступа к Ingress - sort: 120 - - id: 356 - code: accessIpListIngress - data_type: json - required: true - default: '[]' - descr: Access IP List для подключения к Ingress. Указывается массив. Если передан пустой массив, доступ выделяется всем - sort: 130 - is_modifiable: true - - id: 747 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - sort: 20 - - name: delete - id: 109 - kind: instance - action: delete - params: [] - - name: modify - id: 110 - kind: instance - action: modify - params: - - id: 362 - code: controlPlaneCount - data_type: integer > 0 - required: false - maxvalue: 9 - minvalue: 1 - descr: Кол-во нод Control Plane - sort: 10 - - id: 363 - code: workersCount - data_type: integer > 0 - required: false - maxvalue: 99 - minvalue: 1 - descr: Кол-во нод Workers - sort: 20 - - id: 364 - code: accessIpListAPI - data_type: json - required: false - descr: Access IP List для подключения к Kubernetes API. Указывается массив. Если передан пустой массив, доступ выделяется всем - sort: 30 - - id: 365 - code: accessIpListIngress - data_type: json - required: false - descr: Access IP List для подключения к Ingress. Указывается массив. Если передан пустой массив, доступ выделяется всем - sort: 40 - - id: 563 - code: appVersion - data_type: string - required: false - value_list: - - 2.11.0 - - 2.12.1 - descr: Версия Штурвал (не является версией Kubernetes)
Понижать версию нельзя
Обновиться на несколько минорных нельзя
Невозможно перепрыгнуть не с последней минорной на мажорную
Можно обновиться на несколько патчей - - id: 637 - code: controlPlaneSizingDisk - data_type: integer > 0 - required: true - - id: 638 - code: workersSizingDisk - data_type: integer > 0 - required: true - - name: reconcile - id: 253 - kind: action - action: reconcile - params: [] - - name: resume - id: 174 - kind: instance - action: resume - params: [] - - name: suspend - id: 173 - kind: instance - action: suspend - params: [] - - name: update_secrets - id: 179 - kind: action - action: update_secrets - params: [] diff --git a/generated/prod/resources_yaml/19_vc_org.yaml b/generated/prod/resources_yaml/19_vc_org.yaml deleted file mode 100644 index 5efd4a7..0000000 --- a/generated/prod/resources_yaml/19_vc_org.yaml +++ /dev/null @@ -1,85 +0,0 @@ -name: vc_org -service_id: 19 -service_display_name: Организация в Cloud Director -service_short_name: vcOrg -service_man: '# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Url организации
Для быстрого доступа в тенант

### Статус организации
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)** привязанный к этой организации;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к vdc выше.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 136 - kind: instance - action: create - man: '`IaaS` - Доступ в Keycloak предоставляется пользователю, который создаёт услугу
`SaaS` - Без доступа к Keycloak' - params: - - id: 418 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Облако в котором будет развёрнут тенант - man: Выбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы - sort: 10 - - id: 556 - code: organizationType - data_type: string - required: true - default: iaas - value_list: - - iaas - - saas - man: Доступ к организации предоставляется только при выборе `iaas` - sort: 20 - - name: delete - id: 137 - kind: instance - action: delete - man: 'Удалить возможно только через 14 дней после выполнения операции `suspend`
**ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого тенанта**

Если существуют инстансы VDC, Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов' - params: [] - - name: modify - id: 207 - kind: instance - action: modify - man: Для возможности изменения параметров предварительно необходимо создать **Виртуальный датацентр (VDC)**, потом **Сетевой шлюз периметра (Edge Gateway)**
Также при удалении ipSpaces убедитесь, что все внешние IP удалены. В случае если хоть одна привязка vIP есть, данный ipSpace удалён **не будет** - params: - - id: 662 - code: vIPConfigure - data_type: array-map-fixed - required: true - sort: 10 - - name: reconcile - id: 249 - kind: action - action: reconcile - params: [] - - name: resume - id: 144 - kind: instance - action: resume - params: [] - - name: suspend - id: 143 - kind: instance - action: suspend - man: Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри тенанта - params: [] diff --git a/generated/prod/resources_yaml/1_dummy.yaml b/generated/prod/resources_yaml/1_dummy.yaml deleted file mode 100644 index 9a410ce..0000000 --- a/generated/prod/resources_yaml/1_dummy.yaml +++ /dev/null @@ -1,203 +0,0 @@ -name: dummy -service_id: 1 -service_display_name: Болванка -service_short_name: dummy -service_man: '## Болванка для тестов.

А это просто много букв, чтобы посмотреть, как ведет себя текст при переполнении контейнера.


``` json
{
"iamServiceUrl": "https://auth-api-test.ngcloud.ru/api/v1/user",
"idpResponse": {
"prefix": {
"charset": "",
"status_text": "Request Time-out",
"text": true,
"errordetail": "",
"filecontent": "Connection Timeout",
"responseheader": {},
"header": "",
"statuscode": "408 Request Time-out",
"status_code": 408,
"mimetype": "Unable to determine MIME type of file."
}
}
}
```' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 18 - kind: instance - action: create - man: Это мануал к операции CREATE сервиса Болванка - params: - - id: 198 - code: durationMs - data_type: integer >= 0 - required: true - default: "0" - descr: перед завершением подождать (sleep) столько миллисекунд - man: перед завершением подождать (sleep) столько миллисекунд - sort: 20 - is_modifiable: true - - id: 199 - code: failAtStart - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, завершить джоб, ничего не записывая в cmdb - man: '**Операция не будет завершена**
Она будет в постоянном статусе PENDING, однако в Jenkins Job завершится с ошибкой' - sort: 30 - is_modifiable: true - - id: 200 - code: failInProgress - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - man: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - sort: 40 - is_modifiable: true - - id: 201 - code: whereFail - data_type: integer > 0 - required: false - default: "1" - value_list: - - "1" - - "2" - - "3" - descr: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - man: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - sort: 50 - is_modifiable: true - - id: 242 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование ресурсной платформы для подключения - sort: 10 - - id: 286 - code: bodymessage - data_type: string - required: false - descr: Дата, уходящая в Vault - man: Дата, уходящая в Vault - sort: 60 - is_modifiable: true - - id: 321 - code: mapExample - data_type: map - required: false - is_modifiable: true - - id: 322 - code: jsonExample - data_type: json - required: false - descr: Для тестирования интерфейса - man: Для тестирования интерфейса. Сюда можно писать корректный json - is_modifiable: true - - id: 396 - code: nestedRefExample - required: false - - id: 447 - code: yamlExample - data_type: yaml - required: false - - id: 647 - code: mapFixed - data_type: map-fixed - required: false - descr: Новый тип поля - - id: 654 - code: arrayMapFixedExample - data_type: array-map-fixed - required: false - descr: Array of map-fixed - - name: delete - id: 71 - kind: instance - action: delete - params: [] - - name: modify - id: 92 - kind: instance - action: modify - params: - - id: 287 - code: durationMs - data_type: integer >= 0 - required: true - default: "0" - descr: перед завершением подождать (sleep) столько миллисекунд - man: перед завершением подождать (sleep) столько миллисекунд - sort: 10 - - id: 288 - code: failAtStart - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, завершить джоб, ничего не записывая в cmdb - sort: 20 - - id: 289 - code: failInProgress - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - sort: 30 - - id: 290 - code: whereFail - data_type: integer > 0 - required: false - value_list: - - "1" - - "2" - - "3" - descr: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - man: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - sort: 40 - - id: 291 - code: bodymessage - required: false - descr: Дата, уходящая в Vault - man: Дата, уходящая в Vault - sort: 50 - - id: 373 - code: mapExample - data_type: map - required: false - default: '{}' - - id: 374 - code: jsonExample - required: false - - name: redeploy - id: 240 - kind: action - action: redeploy - params: [] - - name: resume - id: 94 - kind: instance - action: resume - params: [] - - name: suspend - id: 93 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/20_vc_org_saas.yaml b/generated/prod/resources_yaml/20_vc_org_saas.yaml deleted file mode 100644 index 1520bdf..0000000 --- a/generated/prod/resources_yaml/20_vc_org_saas.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: vc_org_saas -service_id: 20 -service_display_name: Организация [DEPRECATED] -service_short_name: vcOrgSaas -service_man: 'Верхнеуровневая сущность создаваемая для Заказчика.
Внутри Организация вы можете создать: Виртуальные датацентры, Каталоги.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 8 - kind: instance - action: create - man: Создание организации в Cloud Director
Id в клауд директоре создаётся на основе contragentCode - params: - - id: 185 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование ресурсной платформы - sort: 30 - - name: delete - id: 23 - kind: instance - action: delete - params: [] - - name: resume - id: 119 - kind: instance - action: resume - params: [] - - name: suspend - id: 118 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/21_vc_vdc.yaml b/generated/prod/resources_yaml/21_vc_vdc.yaml deleted file mode 100644 index 759a964..0000000 --- a/generated/prod/resources_yaml/21_vc_vdc.yaml +++ /dev/null @@ -1,153 +0,0 @@ -name: vc_vdc -service_id: 21 -service_display_name: Виртуальный датацентр (vDC) -service_short_name: vc_vdc -service_man: '# Инструкция по развертыванию Виртуальный датацентр (vDC) через платформу

## 1. Общая информация

**Виртуальный датацентр (vDC)** — это логическая изолированная среда в VMware Cloud Director, предназначенная для размещения и управления виртуальными машинами, сетевой инфраструктурой и ресурсами хранения. Сервис обеспечивает выделение вычислительных ресурсов под конкретную организацию и предоставляет гибкие параметры масштабирования, контроля потребления и разделения ресурсов.

### Доступные операции

**create** — Создание виртуального датацентра (vDC) с заданными параметрами CPU, RAM, Storage и сетевой конфигурацией.
**delete** — Удаление vDC. Требуется предварительный перевод vDC в состояние *suspend*. Полное удаление возможно через 14 дней.
**modify** — Внесение изменений в параметры ресурсов (CPU/RAM/Storage), выделенных для vDC.
**suspend** — Заморозка vDC. Новые ресурсы или изменения внутри vDC становятся невозможными, работа ВМ не останавливается.
**resume** — Разморозка vDC. Восстановление возможности управления сущностями внутри vDC.

---

## 2. Параметры развертывания

Ниже перечислены входные параметры операции **create**.

### UUID Организации
Уникальный идентификатор организации в Cloud Director. Перед созданием vDC требуется предварительное создание услугу `Организация в Cloud Director`.

### Provider VDC в Cloud Director
Свойство ресурсной платформы, определяющее, какой пул физических ресурсов будет использоваться.

### Network Pool в Cloud Director
Определяет возможности сетевой конфигурации, включая создание Edge Gateway и выход во внешние сети.

### Гарантированная доля ЯДЕР
Гарантированный процент вычислительных ресурсов (CPU), закрепленный за vDC. Значение устанавливается разово при создании.

### Гарантированная доля ОЗУ
Гарантированный процент оперативной памяти, закрепленный за vDC. Также задаётся один раз при создании.

### Сколько аллоцировать на VDC ЯДЕР
Количество виртуальных ядер, выделяемых в рамках vDC.

### Сколько аллоцировать на VDC ОЗУ
Количество оперативной памяти в GB, выделяемой для vDC.

### Конфигурация Storage
Набор дисковых политик и их объёмов, выделяемых для vDC. Указывается имя политики и требуемый размер (GB).

---

## 3. Рекомендованные характеристики

### Тестовое окружение

- Количество ядер CPU: 10–20
- Аллоцируемая RAM: 16–64 GB
- Гарантированная доля CPU: 20%
- Гарантированная доля RAM: 20%
- Storage:
- Политика `SATA`
- Объём: 100–300 GB

### Промышленное окружение

- Количество ядер CPU: 16–128
- Аллоцируемая RAM: 64–512 GB
- Гарантированная доля CPU: 50%
- Гарантированная доля RAM: 50%
- Storage:
- Политики уровня `SSD`
- Объём: 1–10 TB, выбор несколько политик под разные нагрузки

---

## 4. Выходные параметры

Выходные параметры формируются операцией **create** (и используются другими операциями):

### Имя vDC
Уникальный идентификатор созданного виртуального датацентра. Используется в дальнейших операциях (modify, suspend, delete).

### Параметры выделенных ресурсов
Подтверждение итогового объёма CPU/RAM/Storage, выделенных vDC. Используются для учёта и контроля потребления.

---

## 5. Дополнительная информация

- Перед созданием vDC необходимо обеспечить наличие корректно созданной организации и доступных пула ресурсов ресурсной платформы.
- Гарантированная доля CPU и RAM задаётся **однократно при создании vDC**. После развертывания изменить эти значения невозможно; для изменения необходимо пересоздать vDC.
- Удаление vDC возможно только через **14 дней после перевода в состояние *suspend***. Удаление очищает все связанные сущности (ВМ, сети, каталоги), поэтому необходимо убедиться, что данные перенесены.
- Платформа Cloud Director использует концепцию изолированных организационных ресурсов, поэтому корректная настройка Provider VDC и Network Pool является обязательной при создании vDC.
- При изменении параметров (modify) изменяются только показатели CPU, RAM и Storage. Сетевые параметры и гарантированные доли остаются неизменными.
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 9 - kind: instance - action: create - params: - - id: 30 - code: organizationUid - data_type: uuid - required: true - ref_svc_id: 19 - man: Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` - sort: 10 - - id: 335 - code: providerVdc - data_type: string - required: true - man: Приписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
- sort: 30 - depends_on: organizationUid,networkProvider - - id: 361 - code: storageConfig - data_type: array-map-fixed - required: true - man: Первая политика в списке указывается как "По умолчанию" - sort: 100 - is_modifiable: true - - id: 397 - code: cpuGuaranteed - data_type: integer > 0 - required: true - default: "20" - value_list: - - "20" - - "50" - - "80" - descr: '% резервирования' - man: Свойство нельзя изменить после создания - sort: 60 - - id: 398 - code: memGuaranteed - data_type: integer > 0 - required: true - default: "20" - value_list: - - "20" - - "50" - - "80" - descr: '% резервирования' - man: После создания нельзя изменить - sort: 70 - - id: 557 - code: cpuAllocated - data_type: integer > 0 - required: true - default: "10" - maxvalue: 200 - minvalue: 1 - descr: шт - sort: 80 - is_modifiable: true - - id: 558 - code: memAllocated - data_type: integer > 0 - required: true - default: "20" - maxvalue: 4096 - minvalue: 1 - descr: gb - sort: 90 - is_modifiable: true - - id: 746 - code: networkProvider - data_type: string - required: true - sort: 20 - depends_on: organizationUid - - name: delete - id: 24 - kind: instance - action: delete - man: 'Удалить возможно только через 14 дней после выполнения операции `suspend`
**ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого VDC**

Если существуют инстансы Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов' - params: [] - - name: modify - id: 112 - kind: instance - action: modify - params: - - id: 560 - code: cpuAllocated - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: шт - sort: 10 - - id: 561 - code: memAllocated - data_type: integer > 0 - required: true - maxvalue: 1024 - minvalue: 1 - descr: gb - sort: 20 - - id: 562 - code: storageConfig - data_type: array-map-fixed - required: true - man: Первая политика в списке указывается как "По умолчанию" - sort: 30 - - name: reconcile - id: 250 - kind: action - action: reconcile - params: [] - - name: resume - id: 172 - kind: instance - action: resume - params: [] - - name: suspend - id: 171 - kind: instance - action: suspend - man: Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри VDC - params: [] diff --git a/generated/prod/resources_yaml/22_vc_nsxt.yaml b/generated/prod/resources_yaml/22_vc_nsxt.yaml deleted file mode 100644 index 68fc99c..0000000 --- a/generated/prod/resources_yaml/22_vc_nsxt.yaml +++ /dev/null @@ -1,136 +0,0 @@ -name: vc_nsxt -service_id: 22 -service_display_name: Сетевой шлюз периметра (Edge) -service_short_name: vc_nsxt -service_man: '# Инструкция по развертыванию Сетевой шлюз периметра (Edge) через платформу

## 1. Общая информация

Сервис **Сетевой шлюз периметра (Edge)** предназначен для создания периметрового сетевого шлюза в рамках одного виртуального датацентра (vDC) или группы виртуальных датацентров (groupvDC).
При создании автоматически разворачивается routed-сеть с адресным пространством `10.10.102.0/24`.
Сервис обеспечивает сетевую изоляцию, маршрутизацию, а также может включать функциональность балансировщика нагрузки AVI (ALB) для последующей интеграции, включая поддержку кластеров Штурвал.

### Доступные операции

**create** — Создание нового Edge с привязкой к vDC или groupvDC и развёртыванием routed-сети.
**delete** — Удаление ранее созданного Edge. Недоступно при наличии зависимых услуг (vApp, VM, Кластер Штурвал).
**modify** — Изменение параметров и сетевых настроек существующего Edge.

---

## 2. Параметры развертывания

Ниже приведены параметры операции **create**.

### Тип родительской услуги
Определяет контекст размещения Edge.
Допустимые значения: `vdc`, `groupvdc`.
Использование:
- При выборе `vdc` обязателен параметр **UUID VDC**.
- При выборе `groupvdc` обязателен параметр **UUID Группы VDC**.

### UUID VDC
Идентификатор виртуального датацентра.
Необходимо предварительно создать vDC через услугу «Виртуальный датацентр (vDC)».
Указывается только при выборе родительского типа `vdc`.

### UUID Группы VDC
Идентификатор группы виртуальных датацентров.
Создаётся через услугу «Группа виртуальных датацентров (groupvDC)».
Используется при выборе родительского типа `groupvdc`.

### Включить ALB
Флаг активации AVI Load Balancer в Cloud Director.
Пример значения: `true`/`false`.
Нужен для развёртывания кластера Штурвал и возможности создания Virtual Services.

### Наименование segroup
Имя сервиса групп (segroup) на уровне ресурсной платформы.
Обязательно при включённом ALB.
Определяет группу, в которой будут выделяться пулы AVI для Virtual Services.

### virtualServicesCount
Количество резервируемых виртуальных сервисов (Virtual Services) на AVI.
Типичное значение: 1–10 в зависимости от нагрузки.

---

## 3. Рекомендованные характеристики

### Тестовое окружение (Test)

- Тип родительской услуги: `vdc`
- virtualServicesCount: 1–2
- ALB: выключен по умолчанию (включать только при необходимости тестирования Штурвала)
- segroup: задаётся только при включённом ALB
- VDC гарантии CPU/RAM: минимальные (поскольку изменить их после создания нельзя)

### Промышленное окружение (Production)

- Тип родительской услуги: `groupvdc` при работе с распределёнными нагрузками или `vdc` для локализованных проектов
- virtualServicesCount: 3–10, исходя из предполагаемого количества публикаций
- ALB: включён, если требуется высокая доступность сервисов или используется кластер Штурвал
- segroup: рекомендуется использовать выделенную группу под проект
- VDC гарантии CPU/RAM: повышенные, с учётом того, что изменить их после создания невозможно без пересоздания vDC

---

## 4. Выходные параметры

### Имя Edge
Уникальное название созданного сетевого шлюза, используется для ссылок и дальнейших операций.

### Имя routed-сети
Автоматически созданная routed-сеть с подсетью `10.10.102.0/24`, используется для подключения ресурсов.

### Параметры Edge
Набор параметров, указанных пользователем при создании: тип услуги, ALB, segroup, virtualServicesCount и др.
Используются в операциях modify и для анализа состояния сервиса.

---

## 5. Дополнительная информация

- В рамках сервиса **один раз при создании задаётся гарантированная доля CPU/RAM vDC**. Изменить её невозможно — требуется пересоздание vDC.
- Удаление Edge недоступно при наличии зависимых ресурсов (vApp, VM, кластер Штурвал).
- При использовании ALB необходимо корректно указывать segroup, чтобы обеспечить корректное выделение пулов AVI.
- При выборе режима `groupvdc` следует учитывать распределение нагрузки между несколькими vDC.
- SNAT для всех ресурсов внутри Edge можно активировать через операцию modify (параметры выделения VIP и ipSpace).

' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 10 - kind: instance - action: create - params: - - id: 8 - code: vdcUid - data_type: string - required: false - ref_svc_id: 21 - descr: UUID Услуги `Виртуальный датацентр (vDC)` - man: 'Необходимо, если выбран тип подключаемой VDC: `vdc`' - sort: 10 - - id: 340 - code: needEnableAVI - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включение Load Balancer - man: Параметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указать - sort: 30 - is_modifiable: true - - id: 341 - code: virtualServicesCount - data_type: integer > 0 - required: false - default: "1" - maxvalue: 4 - minvalue: 1 - descr: Кол-во виртуальных сервисов, которые выделяются на AVI - man: Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB` - sort: 50 - is_modifiable: true - - id: 621 - code: vdcType - data_type: string - required: true - default: vdc - value_list: - - vdc - - vdcGroup - descr: Тип родительской услуги - man: При выборе vdc обеспечивает сетевую доступность только в рамках этого vdc
При выборе groupvdc обеспечивает сетевую доступность между всеми vdc, которые включены в groupvdc - sort: 0 - - id: 622 - code: vdcGroupUid - data_type: string - required: false - ref_svc_id: 29 - descr: UUID Услуги `Группа виртуальных датацентров (groupvDC)` - man: 'Необходимо, если выбран тип подключаемой VDC: `groupvdc`' - sort: 20 - - name: delete - id: 25 - kind: instance - action: delete - man: Невозможно удалить если routed-сеть в Edge связана с:
- vApp
- VM
- Kubernetes-кластер Штурвал

Запустить операцию возможно, но будет ошибка - params: [] - - name: modify - id: 111 - kind: instance - action: modify - man: Для создания SNAT Правила убедитесь, что в организации есть свободные IP
Редактировать кол-во свободных IP можно в услуге `Организация в Cloud Director` -> `modify` - params: - - id: 368 - code: needEnableAVI - data_type: boolean - required: false - value_list: - - "false" - - "true" - descr: Включение Load Balancer - man: Параметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указать - sort: 10 - - id: 369 - code: virtualServicesCount - data_type: integer > 0 - required: false - maxvalue: 4 - minvalue: 1 - descr: Кол-во виртуальных сервисов, которые выделяются на AVI - man: Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB` - sort: 30 - - id: 371 - code: needExternalAddressSNAT - data_type: boolean - required: false - value_list: - - "false" - - "true" - descr: Создать правило SNAT на подсеть `10.10.102.0/24` - man: Параметр `ip Space для VIP` станет обязательным, если указан `true` - sort: 40 - - id: 372 - code: ipSpaceName - data_type: string - required: false - descr: Имя ip Space для внешнего IP

getKeyListFromStruct(getInstanceState(getValueFromStruct(getInstanceState(getValueFromStruct(getInstanceState(), "params.vdcUid")), "params.organizationUid")), "params.vIPConfigure") - man: Необходимо указывать, если включён параметр `Выделить VIP для SNAT` - sort: 50 - - name: reconcile - id: 252 - kind: action - action: reconcile - params: [] diff --git a/generated/prod/resources_yaml/23_vc_vm.yaml b/generated/prod/resources_yaml/23_vc_vm.yaml deleted file mode 100644 index 470873d..0000000 --- a/generated/prod/resources_yaml/23_vc_vm.yaml +++ /dev/null @@ -1,153 +0,0 @@ -name: vc_vm -service_id: 23 -service_display_name: VM в Cloud Director (старый формат) (vc_vm) -service_short_name: vc_vm -service_man: Виртуальная машина без каких-либо особенностей.
Данная услуга запускает vc_ip для выдачи белого адреса и подключения к ВМ -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 26 - kind: instance - action: create - params: - - id: 33 - code: vappUid - data_type: uuid - required: true - ref_svc_id: 26 - descr: InstanceUid vApp. vApp должен быть создан - man: InstanceUid vApp. vApp должен быть создан - sort: 10 - - id: 35 - code: vmName - data_type: string - required: true - default: vm0001 - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: Имя ВМ. Не поддерживает спец-символы - man: Имя ВМ. Не поддерживает спец-символы - sort: 20 - - id: 36 - code: vmCpu - data_type: string - required: true - default: "2" - descr: CPU - man: CPU - sort: 30 - is_modifiable: true - - id: 37 - code: vmRam - data_type: string - required: true - default: "2" - descr: RAM (GB) - man: RAM (GB) - sort: 40 - is_modifiable: true - - id: 38 - code: vmDisksize - data_type: string - required: true - default: "10" - descr: Размер диска под сервис (GB) - man: Размер диска под сервис (GB) - sort: 50 - is_modifiable: true - - id: 176 - code: templateName - data_type: string - required: true - default: RockyLinux_9-16G - value_list: - - RockyLinux_9-16G - - OracleLinux_9-16G - - Ubuntu_24-20G - - Ubuntu_22-20G - descr: ОС - man: ОС - sort: 60 - - id: 177 - code: accessIpList - data_type: string - required: true - default: 79.111.119.78/32 185.247.187.1/32 - descr: Вставить содержимое из 'curl ifconfig.io'
IP адреса в CIDR формате через пробел для настройки аксес листов - man: IP адреса в CIDR формате через пробел для настройки аксес листов - sort: 70 - is_modifiable: true - - id: 406 - code: ipSpaceName - data_type: string - required: true - descr: Брать из свойств ресурсной платформы
.vcd.ipSpace

Имя IP-space для выделения внешнего IP (IP выделяется обязательно) - - name: delete - id: 29 - kind: instance - action: delete - params: [] - - name: modify - id: 68 - kind: instance - action: modify - man: Операция автоматически останавливает ВМ. - params: - - id: 186 - code: vmCpu - data_type: integer > 0 - required: false - descr: CPU - man: CPU - sort: 10 - - id: 187 - code: vmRam - data_type: integer > 0 - required: false - descr: RAM - man: RAM - sort: 20 - - id: 188 - code: vmDisksize - data_type: integer > 0 - required: false - descr: Размер диска под сервис (GB) - man: Размер диска под сервис (GB) - sort: 30 - - id: 189 - code: accessIpList - data_type: string - required: false - descr: IP адреса в CIDR формате через пробел для настройки аксес листов - man: IP адреса в CIDR формате через пробел для настройки аксес листов - sort: 40 - - name: resume - id: 28 - kind: instance - action: resume - params: [] - - name: suspend - id: 27 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/25_vcexternalip.yaml b/generated/prod/resources_yaml/25_vcexternalip.yaml deleted file mode 100644 index eaa29b4..0000000 --- a/generated/prod/resources_yaml/25_vcexternalip.yaml +++ /dev/null @@ -1,162 +0,0 @@ -name: vcexternalip -service_id: 25 -service_display_name: Публичные IP адреса -service_short_name: vcexternalip -service_man: '**Обычно эта услуга разворачивается автоматически при развёртывании более сложных услуг**
Вручную создавать можно, однако услуга требует много параметров, о которых можно просто не знать

Резервировать публичные IP адреса можно только после создания NGcloud Organization, NGcloud Виртуальный датацентр, NGcloud Каталог, Сетевой шлюз периметра.
Вы можете назначить IP адрес для существующего экземпляра сервиса.' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 56 - kind: instance - action: create - params: - - id: 140 - code: serviceUid - data_type: string - required: true - sort: 20 - is_modifiable: true - - id: 141 - code: dnatCreate - data_type: boolean - required: true - default: "true" - descr: Необходимо создать DNAT-правило. - sort: 40 - is_modifiable: true - - id: 142 - code: internalPortAccess - data_type: string - required: true - default: "5432" - descr: Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
- sort: 60 - is_modifiable: true - - id: 143 - code: snatCreate - data_type: boolean - required: false - descr: Необходимо создать SNAT-правило.
- sort: 50 - is_modifiable: true - - id: 144 - code: internalAddrAccess - data_type: string - required: true - descr: Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true - sort: 70 - is_modifiable: true - - id: 324 - code: fromServiceNamespace - data_type: string - required: true - descr: Namespace составной услуги (для отображения правил FW) - sort: 80 - - id: 325 - code: fromServiceCloudEdgeName - data_type: string - required: false - descr: Edge составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 90 - - id: 326 - code: fromServiceCloudVdcName - required: false - descr: Vdc составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 100 - - id: 327 - code: fromServiceCloudOrgName - data_type: string - required: false - descr: Org составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 110 - - id: 328 - code: fromServiceCloudVmwareUrl - data_type: string - required: false - descr: Api-Url составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 120 - - id: 336 - code: ipSpaceName - data_type: string - required: true - descr: Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1) - sort: 30 - is_modifiable: true - - id: 488 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 200 - - id: 624 - code: fromServiceCloudEdgeScope - data_type: string - required: false - sort: 130 - - id: 626 - code: fromServiceVdcGroupName - data_type: string - required: false - sort: 140 - - name: delete - id: 57 - kind: instance - action: delete - params: [] - - name: modify - id: 197 - kind: instance - action: modify - params: - - id: 627 - code: serviceUid - data_type: string - required: true - sort: 20 - - id: 628 - code: ipSpaceName - data_type: string - required: true - sort: 30 - - id: 629 - code: dnatCreate - data_type: boolean - required: true - sort: 40 - - id: 630 - code: snatCreate - data_type: boolean - required: true - sort: 50 - - id: 631 - code: internalPortAccess - data_type: string - required: true - sort: 60 - - id: 632 - code: internalAddrAccess - data_type: string - required: true - sort: 70 diff --git a/generated/prod/resources_yaml/26_vapp.yaml b/generated/prod/resources_yaml/26_vapp.yaml deleted file mode 100644 index b48cabd..0000000 --- a/generated/prod/resources_yaml/26_vapp.yaml +++ /dev/null @@ -1,73 +0,0 @@ -name: vapp -service_id: 26 -service_display_name: Виртуальный каталог ВМ (vApp) -service_short_name: vapp -service_man: '# Инструкция по развертыванию Виртуальный каталог ВМ (vApp) через платформу

## 1. Общая информация

**Виртуальный каталог ВМ (vApp)** — это логическая каталог, объединённая в единый управляемый объект. Сервис предназначен для совместного развертывания, управления жизненным циклом и сетевого взаимодействия набора связанных ВМ. Основные функции включают:
- централизованное управление включением, выключением и приостановкой группы ВМ;
- унифицированный сетевой доступ через привязанный Edge-шлюз;

### Доступные операции

**create** — Создание нового vApp с привязкой к заданным услугам VDC и Edge
**delete** — Удаление существующего vApp. Требуется предварительный перевод vApp в состояние *suspend*. Полное удаление возможно через 14 дней.
**suspend** — Остановка vApp (выключение всех ВМ внутри каталога)
**resume** — Запуск vApp (включение всех ВМ внутри каталога)

---

## 2. Параметры развертывания

Параметры берутся из операции **create**.

### UUID Услуги VDC
Уникальный идентификатор услуги «Виртуальный датацентр (vDC)».
Используется для определения вычислительной инфраструктуры, в которой будет развернут vApp.

### UUID Услуги Edge
Уникальный идентификатор услуги «Сетевой шлюз периметра (Edge)».
Обеспечивает маршрутизацию и сетевое подключение. Может быть привязан к группе VDC, поэтому выбирается отдельно.

### Имя vApp
Строгое имя, соответствующее маске формирования DNS-имени.
Используется как часть в DNS-имени при создании виртуальных машин.

---

## 3. Рекомендованные характеристики
Так как является промежуточным этапом для создания ВМ, все характеристики описываются в услуге `Виртуальная машина`

---

## 4. Выходные параметры

### Параметры vApp
Заданные при создании vApp

---

## 5. Дополнительная информация

- Привязка к VDC и Edge осуществляется раздельно, поскольку один Edge может обслуживать несколько VDC (через услугу `Группа виртуальных датацентров (groupvDC)`). Это гарантирует возможность развернуть ВМ в единой сети, но в разных виртуальных датацентрах.
- Перед удалением vApp необходимо вручную перевести его в состояние **suspend**. Удаление возможно только спустя 14 дней после этого шага.
- Операция delete удаляет весь vApp полностью, включая все виртуальные машины, связанные с ним.
- Рекомендуется заранее планировать сетевые связи и назначения DNS-имён для обеспечения корректной работы сервисов, развернутых внутри vApp.
- При проектировании инфраструктуры следует учитывать зависимости между Edge-шлюзом, VDC и размещаемыми ВМ, чтобы избежать ограничений при масштабировании и интеграции.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 69 - kind: instance - action: create - params: - - id: 190 - code: nsxtUid - data_type: uuid - required: true - ref_svc_id: 22 - descr: UUID Услуги `Сетевой шлюз периметра (Edge)` - man: К какой сети может быть подключен виртуальный каталог - sort: 20 - - id: 191 - code: vappName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$ - minlength: 3 - descr: Уникальное в рамках организации - man: Имеет строгую маску `^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$`

Используется в формировании DNS-Имени (для виртуальных машин) - sort: 30 - - id: 623 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - descr: UUID Услуги `Виртуальный датацентр (vDC)` - man: В каких ресурсах будет создан виртуальный каталог - sort: 10 - - name: delete - id: 70 - kind: instance - action: delete - params: [] - - name: resume - id: 209 - kind: instance - action: resume - params: [] - - name: suspend - id: 208 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/27_vc_vm_v2.yaml b/generated/prod/resources_yaml/27_vc_vm_v2.yaml deleted file mode 100644 index 2b1d235..0000000 --- a/generated/prod/resources_yaml/27_vc_vm_v2.yaml +++ /dev/null @@ -1,71 +0,0 @@ -name: vc_vm_v2 -service_id: 27 -service_display_name: VM в Cloud Director (vc_vmV2) -service_short_name: vc_vm_v2 -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 100 - kind: instance - action: create - params: - - id: 301 - code: serverListJson - data_type: json - required: true - default: '[{}]' - maxlength: 65536 - minlength: 10 - descr: Необходимо изменить vappUid и ipSpaceName
Пример конфигурации взять по ссылке ниже

Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2) - sort: 20 - is_modifiable: true - - name: delete - id: 101 - kind: instance - action: delete - params: [] - - name: modify - id: 104 - kind: instance - action: modify - params: - - id: 302 - code: serverListJson - data_type: json - required: true - default: '[{}]' - maxlength: 65536 - minlength: 10 - descr: Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2) - sort: 10 - - name: resume - id: 102 - kind: instance - action: resume - params: [] - - name: suspend - id: 103 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/28_vc_vm_v3.yaml b/generated/prod/resources_yaml/28_vc_vm_v3.yaml deleted file mode 100644 index 559975c..0000000 --- a/generated/prod/resources_yaml/28_vc_vm_v3.yaml +++ /dev/null @@ -1,272 +0,0 @@ -name: vc_vm_v3 -service_id: 28 -service_display_name: Виртуальная машина -service_short_name: vc_vm_v3 -service_man: '# Документация по разворачиванию ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\ложь, определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed" (В нем не будет работать сбор метрик zabbix).

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 132 - kind: instance - action: create - man: '# Документация по использованию услуги развёртывания ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\лож определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed".

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики' - params: - - id: 407 - code: vappUid - data_type: uuid - required: true - ref_svc_id: 26 - sort: 10 - - id: 408 - code: vmName - data_type: string - required: true - default: web01 - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - sort: 20 - - id: 409 - code: vmCpu - data_type: integer > 0 - required: true - default: "1" - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 30 - is_modifiable: true - - id: 410 - code: vmRam - data_type: integer > 0 - required: true - default: "1" - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 40 - is_modifiable: true - - id: 411 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 50 - is_modifiable: true - - id: 412 - code: ipSpaceName - data_type: string - required: true - sort: 60 - depends_on: vappUid - is_modifiable: true - - id: 413 - code: accessIpList - data_type: json - required: false - regex: ^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$ - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 70 - is_modifiable: true - - id: 414 - code: imageVm - data_type: string - required: true - sort: 90 - depends_on: vappUid - - id: 415 - code: cloudInit - data_type: yaml - required: false - descr: Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. - sort: 200 - - id: 416 - code: userLogin - required: true - default: myuser - descr: Учётка SSH - sort: 180 - - id: 417 - code: userPublicKey - data_type: string - required: true - descr: Публичная часть SSH-Ключа для пользователя - sort: 190 - - id: 448 - code: accessPortList - data_type: string - required: true - default: '["22"]' - descr: 'По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX' - sort: 80 - is_modifiable: true - - name: delete - id: 133 - kind: instance - action: delete - params: [] - - name: modify - id: 159 - kind: instance - action: modify - params: - - id: 493 - code: vmCpu - data_type: integer > 0 - required: false - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 20 - - id: 494 - code: vmRam - data_type: integer > 0 - required: false - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 30 - - id: 495 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 40 - - id: 496 - code: ipSpaceName - data_type: string - required: false - value_list: - - no-needed - - internet-antiddos-v1 - - internet-no-antiddos-v1 - descr: no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev - sort: 50 - - id: 497 - code: accessIpList - data_type: json - required: false - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 60 - - id: 498 - code: accessPortList - data_type: json - required: false - descr: Формат массива
По каким портам открыть доступ к ВМ.
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS - sort: 70 - - name: redeploy - id: 164 - kind: action - action: redeploy - params: - - id: 509 - code: vmName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - sort: 10 - - id: 510 - code: vmCpu - data_type: integer > 0 - required: true - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 20 - - id: 511 - code: vmRam - data_type: integer > 0 - required: true - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 30 - - id: 512 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 40 - - id: 513 - code: ipSpaceName - data_type: string - required: false - value_list: - - no-needed - - internet-antiddos-v1 - - internet-no-antiddos-v1 - - internet-ipv4-v1 - descr: no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev - sort: 50 - - id: 514 - code: accessIpList - data_type: json - required: false - regex: ^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$ - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 60 - - id: 515 - code: imageVm - data_type: string - required: true - value_list: - - RockyLinux_9-16G-cloudinit - - Ubuntu_22-20G - - Debian_13-20G - sort: 80 - - id: 516 - code: userLogin - data_type: string - required: true - descr: Учётка SSH - sort: 180 - - id: 517 - code: userPublicKey - data_type: string - required: true - descr: Публичная часть SSH-Ключа для пользователя - sort: 190 - - id: 518 - code: cloudInit - data_type: yaml - required: false - descr: Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. - sort: 200 - - id: 520 - code: accessPortList - data_type: json - required: false - descr: По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX - sort: 70 - - name: resume - id: 135 - kind: instance - action: resume - params: [] - - name: suspend - id: 134 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/29_vc_vdc_group.yaml b/generated/prod/resources_yaml/29_vc_vdc_group.yaml deleted file mode 100644 index efec3aa..0000000 --- a/generated/prod/resources_yaml/29_vc_vdc_group.yaml +++ /dev/null @@ -1,72 +0,0 @@ -name: vc_vdc_group -service_id: 29 -service_display_name: Группа датацентров -service_short_name: vcVdcGroup -service_man: '# Инструкция по развертыванию Группа виртуальных датацентров (groupvDC) через платформу

## 1. Общая информация

Сервис **Группа виртуальных датацентров (groupvDC)** предназначен для логического объединения нескольких виртуальных датацентров (vDC) в единую группу. Это позволяет растягивать SDN между разными vDC и централизованно управлять сетевой связностью. Управление инфраструктурой осуществляется через Cloud Director.
Сервис применяется в случаях, когда требуется обеспечить единое сетевое пространство для распределенных виртуальных датацентров.

### Доступные операции

**create** — Создание новой группы виртуальных датацентров.
**delete** — Удаление существующей группы vDC.
**add_vdc** — Добавление дополнительного виртуального датацентра в группу.
**remove_vdc** — Удаление ранее добавленного виртуального датацентра из группы.

---

## 2. Параметры развертывания

Параметры операции **create**:

### UUID VDC
Идентификатор виртуального датацентра, который будет являться первичным в группе.
Описание: требуется предварительно создать виртуальный датацентр с помощью услуги `Виртуальный датацентр (vDC)`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Для тестового окружения создавать группу VDC нет необходимости, так как это создаёт дополнительный слой абстракции в Cloud Director

### Промышленное окружение
- Для промышленного окружения, если в тенанте существуют разные VDC, создание groupvdc позволит снизить сетевые издержки (за счёт общей сети)

---

## 4. Выходные параметры

### Параметры groupvdc
Набор параметров, указанных пользователем при создании

---

## 5. Дополнительная информация
- Группа vDC используется для растягивания SDN между несколькими виртуальными датацентрами. Управление всеми сетевыми элементами внутри группы выполняется Cloud Director.
- Удалить первичный vDC (тот, что был указан при операции **create**) невозможно. Для его удаления необходимо удалить всю группу и создать новую.
- Перед добавлением любого vDC в группу он должен быть предварительно развернут через сервис `Виртуальный датацентр (vDC)`.
- Сети создаются не в этой услуге, а в услуге `Сетевой шлюз периметра (Edge)`. В ней необходимо будет выбрать тип `groupvdc`' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: add_vdc - id: 192 - kind: action - action: add_vdc - man: '**Не нужно** выбирать UUID VDC, который уже был добавлен в группу' - params: - - id: 619 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - sort: 10 - - name: create - id: 191 - kind: instance - action: create - man: '**VDC Группа** нужна для объединения всех VDC в организации в одну логическую группу.
Это позволит, к примеру, создать **общую сеть** для всех VDC в организации

- Для создания группы VDC необходимо указать **инстанс** услуги VDC (`Виртуальный датацентр`)
- **Важный момент** - удалить эту VDC из группы нельзя. Если такая потребность появится, необходимо будет **ПОЛНОСТЬЮ** удалить группу VDC и уже потом создать новую' - params: - - id: 618 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - sort: 10 - - name: delete - id: 195 - kind: instance - action: delete - params: [] - - name: reconcile - id: 251 - kind: action - action: reconcile - params: [] - - name: remove_vdc - id: 193 - kind: action - action: remove_vdc - params: - - id: 620 - code: vdcName - data_type: string - required: true - sort: 10 diff --git a/generated/prod/resources_yaml/2_template.yaml b/generated/prod/resources_yaml/2_template.yaml deleted file mode 100644 index d37f0bd..0000000 --- a/generated/prod/resources_yaml/2_template.yaml +++ /dev/null @@ -1,128 +0,0 @@ -name: template -service_id: 2 -service_display_name: Темплейт k8s -service_short_name: template -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 74 - kind: instance - action: create - params: - - id: 202 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 100 - is_modifiable: true - - id: 203 - code: resourceMemory - data_type: integer > 0 - required: true - default: "200" - maxvalue: 8192 - minvalue: 128 - is_modifiable: true - - id: 204 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - is_modifiable: true - - id: 205 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - is_modifiable: true - - id: 206 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - id: 207 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - - name: delete - id: 75 - kind: instance - action: delete - params: [] - - name: modify - id: 76 - kind: instance - action: modify - params: - - id: 208 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - - id: 209 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - - id: 210 - code: resourceDisk - data_type: integer > 0 - required: false - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - - id: 211 - code: resourceInstances - data_type: integer > 0 - required: false - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - - name: resume - id: 98 - kind: instance - action: resume - params: [] - - name: suspend - id: 97 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/32_vmpostgre.yaml b/generated/prod/resources_yaml/32_vmpostgre.yaml deleted file mode 100644 index 0d022fb..0000000 --- a/generated/prod/resources_yaml/32_vmpostgre.yaml +++ /dev/null @@ -1,80 +0,0 @@ -name: vmpostgre -service_id: 32 -service_display_name: vc_vm_postgresql_std -service_short_name: vmpostgre -service_man: Сервис настройки PostgreSQL для виртуальной машины.
Требует наличия ВМ -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 32 - kind: instance - action: create - params: - - id: 43 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - descr: InstanceUid vdc. Vdc должен быть создан
- - id: 44 - code: nsxtUid - data_type: uuid - required: true - ref_svc_id: 22 - descr: InstanceUid nsxt. Nsxt должен быть создан
- - id: 45 - code: vmUid - data_type: uuid - required: true - ref_svc_id: 23 - descr: InstanceUid ВМ. ВМ должна быть создана
- - id: 46 - code: userDb - data_type: string - required: true - default: servicedb - descr: Наименование Базы данных
- - id: 47 - code: userLogin - data_type: string - required: true - default: serviceuser - descr: Пользователь базы данных
- - id: 48 - code: userPassword - data_type: string - required: true - default: fj29gm48fm!d374mc9 - descr: Пароль от доступа к Базе данных
- - id: 859 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Ресурсная платформа - - name: delete - id: 33 - kind: instance - action: delete - params: [] diff --git a/generated/prod/resources_yaml/50_nextcloud.yaml b/generated/prod/resources_yaml/50_nextcloud.yaml deleted file mode 100644 index b64448e..0000000 --- a/generated/prod/resources_yaml/50_nextcloud.yaml +++ /dev/null @@ -1,184 +0,0 @@ -name: nextcloud -service_id: 50 -service_display_name: Nextcloud -service_short_name: nextcloud -service_man: 'Ресурсная платформа: k8s. Автоматизация: helm chart' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 16 - kind: instance - action: create - man: DEV-Ветка сборки Nextcloud - params: - - id: 21 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Наименование домена. Если будет указан FQDN, то происходят проверки DNS. Если указан поддомен, то будет добавлен в зону services.ngcloud.ru
Можно указать клиентскую DNS-Запись. Важно, чтобы запись смотрела на Ingress кластера - sort: 10 - - id: 99 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili - man: Квота ядра пода (Указывается в mili). 1 ядро = 1000 Mili - sort: 30 - is_modifiable: true - - id: 100 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1024" - maxvalue: 8192 - minvalue: 1024 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 40 - is_modifiable: true - - id: 101 - code: resourceDisk - data_type: integer > 0 - required: true - default: "2" - maxvalue: 999 - minvalue: 2 - descr: Квота диска (Указывается в GIGAbytes)
Диск не может быть меньше 2G (!) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 192 - code: documentServer - data_type: string - required: true - default: collabora - value_list: - - collabora - descr: Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен
Размер пода collabora:
1.8 ядра. 2Gi ОЗУ - man: Выбор сервера документов (onlyoffice)/(collabora). onlyoffice пока не доступен - sort: 100 - - id: 470 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - value_list: - - "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов
Не может пока быть больше одного, так как нужны SC под RWMany - sort: 60 - is_modifiable: true - - id: 564 - code: psqlUid - data_type: uuid - required: true - ref_svc_id: 90 - sort: 6 - - id: 569 - code: appVersion - required: true - default: 32.0.1 - value_list: - - 32.0.1 - sort: 20 - is_modifiable: true - - id: 570 - code: redisUid - data_type: uuid - required: true - ref_svc_id: 91 - sort: 7 - - name: delete - id: 17 - kind: instance - action: delete - man: DEV-Ветка удаления Nextcloud - params: [] - - name: modify - id: 67 - kind: instance - action: modify - params: - - id: 178 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) - man: Квота ядра пода (Указывается в mili) - - id: 179 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - - id: 180 - code: resourceDisk - data_type: integer > 0 - required: false - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - - id: 547 - code: resourceInstances - data_type: integer > 0 - required: false - value_list: - - "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов.
Не может пока быть больше одного, так как нужны SC под RWMany - - id: 571 - code: appVersion - data_type: string - required: true - value_list: - - 32.0.1 - descr: Нельзя обновляться сразу через несколько версий сразу - - name: restart - id: 66 - kind: action - action: restart - params: [] - - name: resume - id: 129 - kind: instance - action: resume - params: [] - - name: suspend - id: 128 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/81_superset.yaml b/generated/prod/resources_yaml/81_superset.yaml deleted file mode 100644 index e935cbe..0000000 --- a/generated/prod/resources_yaml/81_superset.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: superset -service_id: 81 -service_display_name: Apache Superset -service_short_name: superset -service_man: 'Apache Superset как сервис.
Ресурсная платформа: k8s.
Автоматизация: k8s operator.
Авторизация: 2FA keycloak (для доменного логина @mgmt.nubes.ru)' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 12 - kind: instance - action: create - man: DEV-Ветка сборки Superset - params: - - id: 14 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 20 - code: emails - data_type: string - required: true - default: testuser1 - descr: Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - man: Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - sort: 70 - - id: 96 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - man: Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - sort: 30 - - id: 97 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 40 - - id: 98 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - - id: 109 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 227 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 60 - - name: delete - id: 13 - kind: instance - action: delete - man: DEV-Ветка удаления Superset - params: [] diff --git a/generated/prod/resources_yaml/82_harbor.yaml b/generated/prod/resources_yaml/82_harbor.yaml deleted file mode 100644 index c47b0df..0000000 --- a/generated/prod/resources_yaml/82_harbor.yaml +++ /dev/null @@ -1,103 +0,0 @@ -name: harbor -service_id: 82 -service_display_name: Container Registry -service_short_name: harbor -service_man: 'Расширенный реестр для управления Docker-образами с enterprise-функциями безопасности, репликации и контроля доступа.
Container Registry позволяет хранить, развертывать и управлять Docker-образами контейнеров в инфраструктуре NGcloud.
Сервис можно использовать в процессе разработки контейнеров. Например, вы можете настроить систему автоматизации на работу с реестром в Container Registry в рамках процесса непрерывной интеграции. Контейнеры идеально подходят для запуска небольших, независимых и легко изменяемых сервисов.
Чтобы начать работу, создайте реестр и загрузите в него Docker-образ
Авторизация: keycloak' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 14 - kind: instance - action: create - man: DEV-Ветка сборки Harbor - params: - - id: 16 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 20 - - id: 17 - code: emails - data_type: string - required: true - default: testuser1 - descr: Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел - man: Учётная запись, которой будут выданы админские права. Обязана находиться в Keycloak. Можно передавать несколько через пробел - sort: 70 - - id: 110 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 30 - - id: 228 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 40 - - id: 229 - code: resourceMemory - data_type: integer > 0 - required: true - default: "200" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 50 - - id: 230 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 60 - - id: 231 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: UUID экземпляра услуги S3 - man: UUID экземпляра услуги S3 - sort: 10 - - name: delete - id: 15 - kind: instance - action: delete - man: DEV-Ветка удаления Harbor - params: [] diff --git a/generated/prod/resources_yaml/88_k8s_ziti_controller.yaml b/generated/prod/resources_yaml/88_k8s_ziti_controller.yaml deleted file mode 100644 index 7270f20..0000000 --- a/generated/prod/resources_yaml/88_k8s_ziti_controller.yaml +++ /dev/null @@ -1,90 +0,0 @@ -name: k8s_ziti_controller -service_id: 88 -service_display_name: k8sZitiController -service_short_name: k8sZitiController -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 99 - kind: instance - action: create - params: - - id: 294 - code: resourceCPU - data_type: integer > 0 - required: true - default: "300" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - sort: 30 - - id: 295 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - sort: 40 - - id: 296 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - - id: 297 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 60 - - id: 298 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 20 - - id: 299 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - name: delete - id: 105 - kind: instance - action: delete - params: [] diff --git a/generated/prod/resources_yaml/89_flask.yaml b/generated/prod/resources_yaml/89_flask.yaml deleted file mode 100644 index 114e992..0000000 --- a/generated/prod/resources_yaml/89_flask.yaml +++ /dev/null @@ -1,156 +0,0 @@ -name: flask -service_id: 89 -service_display_name: Flask -service_short_name: flask -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 88 - kind: instance - action: create - params: - - id: 248 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 249 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 20 - - id: 250 - code: resourceCPU - data_type: integer > 0 - required: true - default: "300" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - sort: 30 - is_modifiable: true - - id: 251 - code: resourceMemory - data_type: integer > 0 - required: true - default: "256" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 252 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 50 - is_modifiable: true - - id: 253 - code: gitPath - data_type: string - required: true - default: https://github.com/Foxyhhd/Baldurs-Gate-test.git - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 60 - is_modifiable: true - - id: 254 - code: jsonEnv - data_type: string - required: false - default: '{ "param": "value" }' - descr: Массив переменных, будут переданы в env приложения - sort: 70 - is_modifiable: true - - id: 255 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код - sort: 80 - - name: delete - id: 89 - kind: instance - action: delete - params: [] - - name: modify - id: 146 - kind: instance - action: modify - params: - - id: 451 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - sort: 10 - - id: 452 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - sort: 20 - - id: 453 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 30 - - id: 454 - code: gitPath - required: true - descr: Путь до Git, который будет webroot для сайта - sort: 40 - - id: 455 - code: jsonEnv - data_type: json - required: true - default: '{ "param": "value" }' - descr: Массив переменных, будут переданы в env приложения - sort: 50 - - name: resume - id: 145 - kind: instance - action: resume - params: [] - - name: suspend - id: 125 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/90_postgres.yaml b/generated/prod/resources_yaml/90_postgres.yaml deleted file mode 100644 index befa68d..0000000 --- a/generated/prod/resources_yaml/90_postgres.yaml +++ /dev/null @@ -1,468 +0,0 @@ -name: postgres -service_id: 90 -service_display_name: PostgreSQL -service_short_name: postgres -service_man: '# Инструкция по развертыванию PostgreSQL через платформу

---
## 1. Общая информация

PostgreSQL — это надёжная объектно-реляционная СУБД с открытым исходным кодом, поддерживающая расширенный набор функций, транзакции и хранение сложных типов данных. Развёртывание полностью автоматизировано платформой на базе Zalando Postgres Operator с использованием Kubernetes.

## Доступные операции

- **create** — Создание кластера
- **delete** — Удаление кластера
- **modify** — Модификация кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера
- **restart** — Перезапуск кластера
- **recovery** — Восстановление из резервной копии

- **create_user** — Создание пользователя
- **delete_user** — Удаление пользователя

- **create_database** — Создание базы данных
- **delete_database** — Удаление базы данных


---
## 2. Параметры развертывания кластера

Ниже перечислены параметры, которые необходимо указать при создании ресурса PostgreSQL:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество инстансов (реплик) в кластере PostgreSQL. Пример: `2` (master + slave).

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных в гигабайтах. Пример: `20`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`

* **Выделяет внешний IP для доступа к slave:**
Флаг для выделения внешнего IP для slave (реплики чтения). Работает, если slave присутствует в кластере.

* **Имя ipSpace для публикации внешнего IP slave:**
Если включен параметр для slave, то поле необходимо заполнить.

* **UUID экземпляра услуги S3:**
UUID экземпляра S3 для хранения резервных копий.

* **Версия PostgreSQL:**
Версия PostgreSQL для развертывания. Пример: `16`

* **Расписание бэкапов (ext_BACKUP_SCHEDULE):**
Необязательный. Cron-выражение для времени запуска бэкапов. По умолчанию: `0 0 * * *` (ежедневно в полночь).

* **Количество сохраняемых бэкапов (ext_BACKUP_NUM_TO_RETAIN):**
Необязательный. Количество сохраняемых бэкапов. По умолчанию: `7`

* **PgPooler (master / slave):**
Флаги включения PgBouncer для подключений на запись и чтение. При включении создаётся отдельный под.

* **Разрешить подключение без SSL (allowNoSSL):**
По умолчанию подключение с sslmode=require. При `true` разрешается подключение без SSL.

* **Автоскейлинг PV (autoScale):**
Включает автоскейлинг тома. Требует настройки autoScalePercentage, autoScaleTechWindow, autoScaleQuotaGb.

* **Дополнительные параметры PostgreSQL (jsonParameters):**
JSON с переменными конфигурации PostgreSQL. Документация: https://www.postgresql.org/docs/current/runtime-config.html

---
## 3. Выходные параметры

После успешного развертывания ресурса PostgreSQL платформа возвращает ряд параметров.

#### externalConnect

Внешние эндпоинты для подключения к кластеру:
- **master** — для операций записи (host: `write.${namespace}`, port: 5432)
- **slave** — для операций чтения (host: `read.${namespace}`, port: 5432)

Пример ответа платформы:

```json
{
"slave": {
"ip": "",
"fqdn": "",
"uuid": "",
"isExternal": false
},
"master": {
"ip": "<ip>",
"fqdn": "write.<namespace>.<cluster-domain>",
"uuid": "<uuid>",
"isExternal": false
}
}
```

Поля: `ip` — внешний IP; `fqdn` — полное имя хоста; `uuid` — идентификатор; `isExternal` — признак внешнего доступа.

#### internalConnect

Внутренние эндпоинты (FQDN) для подключения из других сервисов внутри той же сети Kubernetes.

Пример ответа платформы:

```json
{
"slave": "",
"master": {
"slave": "",
"master": {
"slave": "",
"master": "postgresqlk8s-master.<namespace>.svc.cluster.local"
}
}
}
```

Для подключения используйте значение `master.master.master` (host для записи) или соответствующее значение slave (host для чтения).

Для подключения используется порт **5432**.

---
## 4. Управление пользователями

### create_user — Создание пользователя

* **Имя пользователя (username):**
Имя создаваемого пользователя. Используется для подключения к базе и настройки прав.
Пример: `myapp_user`

* **Роль (role):**
Тип роли пользователя. Допустимые значения:
- `app_user` — базовые права для DML-операций (SELECT, INSERT, UPDATE, DELETE)
- `ddl_user` — расширенные права: createdb, createrole (управление базами и ролями)

Защищённые имена, которые нельзя использовать: `admin`, `postgres`, `standby`.

### delete_user — Удаление пользователя

* **Имя пользователя (username):**
Имя удаляемого пользователя. Пример: `myapp_user`

Пользователя нельзя удалить, если он является владельцем базы данных. Сначала удалите или передайте владение базами данных другому пользователю.

---
## 5. Управление базами данных

### create_database — Создание базы данных

* **Имя базы данных (dbName):**
Название создаваемой базы данных. Пример: `myapp_db`

* **Владелец базы данных (dbOwner):**
Имя пользователя-владельца базы. Должен существовать в кластере (создан через create_user). Пример: `myapp_user`

### delete_database — Удаление базы данных

* **Имя базы данных (dbName):**
Название удаляемой базы данных. Пример: `myapp_db`
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 19 - kind: instance - action: create - man: руководство - params: - - id: 23 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - man: Экземпляр (учетная запись) S3 для резервного копирования. Резервное копирование обязательно - sort: 20 - - id: 80 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - regex: ^[1357]$ - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в кластере. 1,3,5,7 - sort: 60 - is_modifiable: true - - id: 81 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 82 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - man: Квота ядра пода (milicores) - sort: 30 - is_modifiable: true - - id: 83 - code: resourceDisk - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 102 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Кластер Kubernetes, на котором будет развернут экземпляр - sort: 10 - - id: 145 - code: needExternalAddressMaster - data_type: boolean - required: false - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к master - man: Выделяет внешний (белый) IP для доступа к master - sort: 70 - is_modifiable: true - - id: 146 - code: needExternalAddressSlave - data_type: boolean - required: false - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть - man: Выделяет внешний (белый) IP для доступа к slave. Будет работать, если slave в принципе есть - sort: 90 - is_modifiable: true - - id: 265 - code: ext_BACKUP_SCHEDULE - data_type: string - required: false - default: 0 0 * * * - regex: ^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$ - man: Не обязательный. Время запуска бекапа - sort: 150 - is_modifiable: true - - id: 266 - code: ext_BACKUP_NUM_TO_RETAIN - data_type: integer > 0 - required: false - default: "7" - maxvalue: 99 - minvalue: 1 - man: Не обязательный. Количество сохраняемых бекапов - sort: 140 - is_modifiable: true - - id: 310 - code: appVersion - data_type: string - required: true - default: "17" - value_list: - - "17" - - "16" - - "15" - - "14" - - "13" - descr: Версия PostgreSQL - sort: 160 - is_modifiable: true - - id: 311 - code: jsonParameters - data_type: json - required: true - default: '{ "log_connections": "off", "log_disconnections": "off" }' - maxlength: 2048 - descr: Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html - sort: 170 - is_modifiable: true - - id: 312 - code: enablePgPoolerMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает pgPooler (на запись). Будет создан новый под - sort: 180 - is_modifiable: true - - id: 313 - code: enablePgPoolerSlave - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает pgPooler (на чтение). Будет создан новый под - sort: 190 - is_modifiable: true - - id: 314 - code: allowNoSSL - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр - sort: 200 - is_modifiable: true - - id: 329 - code: autoScale - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает автоскейлинг PV. При включении параметра необходимо настроить autoScalePercentage и autoScaleTechWindow. Алерт при срабатывании вызывает modify у текущей услуги - sort: 300 - - id: 330 - code: autoScalePercentage - data_type: integer > 0 - required: true - default: "10" - value_list: - - "10" - - "15" - - "20" - descr: Требует включения autoScale. Позволяет указать в процентах расширение от текущего макс объема - sort: 310 - - id: 331 - code: autoScaleTechWindow - data_type: integer >= 0 - required: true - default: "0" - value_list: - - "0" - - "5" - - "12" - - "23" - descr: Требует включения autoScale. Окно обновления (пока не реализовано). Указывается час в виде Integer (0 / 5 / 12 / 23) - sort: 320 - - id: 337 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`' - sort: 80 - is_modifiable: true - - id: 338 - code: ipSpaceNameSlave - data_type: string - required: false - descr: Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave - sort: 100 - is_modifiable: true - - id: 339 - code: autoScaleQuotaGb - data_type: string - required: true - default: "1" - descr: Квота для autoScale - sort: 330 - - name: delete - id: 20 - kind: instance - action: delete - params: - - id: 457 - code: deleteS3Bucket - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Также удалить технический S3 Bucket с бэкапами? - sort: 10 - - name: modify - id: 48 - kind: instance - action: modify - params: - - id: 91 - code: resourceInstances - data_type: integer > 0 - required: false - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 40 - - id: 92 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 20 - - id: 93 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - man: Квота ядра пода (milicores) - sort: 10 - - id: 94 - code: resourceDisk - data_type: integer > 0 - required: false - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 30 - - id: 147 - code: needExternalAddressMaster - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Выделяет внешний IP для доступа к master - man: Выделяет внешний IP для доступа к master - sort: 50 - - id: 148 - code: needExternalAddressSlave - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Выделяет внешний IP для доступа к slave. Действует, если slave в принципе есть - man: Выделяет внешний IP для доступа к slave. Действует, если slave в принципе есть - sort: 70 - - id: 267 - code: ext_BACKUP_SCHEDULE - data_type: string - required: false - regex: ^((((\d+,)+\d+|(\d+(\/|-|#)\d+)|(\d+L?)|(\*(\/\d+)?)|(L(-\d+)?)|(\?)|([A-Z]{3}(-[A-Z]{3})?)) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)$ - man: Не обязательный. Время запуска бекапа - sort: 90 - - id: 268 - code: ext_BACKUP_NUM_TO_RETAIN - data_type: integer > 0 - required: false - maxvalue: 99 - minvalue: 1 - man: Не обязательный. Количество сохраняемых бекапов - sort: 100 - - id: 315 - code: appVersion - data_type: string - required: true - value_list: - - "17" - - "16" - - "15" - - "14" - - "13" - descr: Версия PostgreSQL. Нельзя опускать вниз - sort: 110 - - id: 316 - code: jsonParameters - data_type: json - required: false - maxlength: 2048 - descr: Массив переменных, более подробнее про настройку можно посмотреть https://www.postgresql.org/docs/current/runtime-config.html - sort: 120 - - id: 317 - code: enablePgPoolerMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает pgPooler (на запись). Будет создан новый под - sort: 130 - - id: 318 - code: enablePgPoolerSlave - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает pgPooler (на чтение). Будет создан новый под - sort: 140 - - id: 319 - code: allowNoSSL - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: По умолчанию подключение обязательное (sslmode=require). Выставление в true отключит этот параметр - sort: 150 - - id: 541 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster. Пример: `internet-no-antiddos-v1`' - sort: 60 - - id: 542 - code: ipSpaceNameSlave - data_type: string - required: false - descr: Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave - sort: 80 - - name: recovery - id: 47 - kind: action - action: recovery - params: - - id: 86 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети
- sort: 50 - - id: 87 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes)
- man: Квота памяти пода (Указывается в Megabytes)
- sort: 30 - - id: 88 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili)
- man: Квота ядра пода (Указывается в mili)
- sort: 20 - - id: 89 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 40 - - id: 131 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 10 - - name: restart - id: 54 - kind: action - action: restart - man: ВНИМАНИЕ - Рестарт предполагает УДАЛЕНИЕ подов.
Может быть полная поломка. Крайне осторожно запускать при работе - params: [] - - name: resume - id: 114 - kind: instance - action: resume - params: [] - - name: suspend - id: 115 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/91_redis.yaml b/generated/prod/resources_yaml/91_redis.yaml deleted file mode 100644 index a710a58..0000000 --- a/generated/prod/resources_yaml/91_redis.yaml +++ /dev/null @@ -1,118 +0,0 @@ -name: redis -service_id: 91 -service_display_name: Redis -service_short_name: redis -service_man: 'Redis кластер. Под кеши.
Ресурсная платформа: k8s.
Автоматизация: k8s operator
port 6379' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 21 - kind: instance - action: create - params: - - id: 112 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (Указывается в mili) - man: Квота ядра пода (Указывается в mili) - sort: 20 - - id: 113 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1024" - maxvalue: 8192 - minvalue: 512 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 30 - - id: 114 - code: resourceDisk - data_type: integer > 0 - required: true - default: "30" - maxvalue: 999 - minvalue: 10 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 40 - - id: 181 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети. Если выделить больше 1 ноды, будет добавлено дополнительно 3 Sentinel ноды - sort: 50 - - id: 182 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения
- sort: 10 - - id: 183 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний IP для доступа к master - man: Выделяет внешний IP для доступа к master - sort: 60 - - id: 184 - code: needExternalAddressSlave - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть - man: Выделяет внешний IP для доступа к slave. Будет работать если slave в целом есть - sort: 70 - - id: 548 - code: ipSpaceNameMaster - data_type: string - required: false - descr: Имя ipSpace для публикации VIP master. Не может быть пустым, если включен needExternalAddressMaster - - id: 549 - code: ipSpaceNameSlave - data_type: string - required: false - descr: Имя ipSpace для публикации VIP slave. Не может быть пустым, если включен needExternalAddressSlave - - name: delete - id: 22 - kind: instance - action: delete - params: [] diff --git a/generated/prod/resources_yaml/92_mongodb.yaml b/generated/prod/resources_yaml/92_mongodb.yaml deleted file mode 100644 index 2130bab..0000000 --- a/generated/prod/resources_yaml/92_mongodb.yaml +++ /dev/null @@ -1,147 +0,0 @@ -name: mongodb -service_id: 92 -service_display_name: MongoDB -service_short_name: mongodb -service_man: '# Инструкция по развертыванию MongoDB через платформу

## 1. Общая информация

MongoDB — документоориентированная распределённая база данных, обеспечивающая высокую доступность, горизонтальное масштабирование и гибкую модель хранения.

### Доступные операции с кластером

* **create** — создание кластера
* **delete** — удаление кластера
* **suspend** — остановка кластера
* **resume** — запуск кластера

### Доступные операции с пользователями

* **create_user** — создание пользователя
* **modify_user** — модификация пользователя
* **delete_user** — удаление пользователя

---

## 2. Параметры развертывания кластера

Эти параметры необходимо указать при создании кластера.

### Платформа для развертывания

Среда, в которой будет развернут кластер. Выбирается из предложенного списка.

### Количество узлов

Оптимально выбирать нечётное количество узлов в кластере MongoDB, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность кластера даже при отказе одной из нод.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных в гигабайтах.
Пример: `20`

### Выделение внешнего IP для доступа к master

Флаг, определяющий необходимость выделения внешнего IP.
Допустимые значения: `true` или `false`

### Имя ipSpace для публикации внешнего IP

Указывается только если включено выделение внешнего IP.
Пример: `internet-no-antiddos-v1`

---

## 3. Параметры создания пользователя

### Имя пользователя

Указывается имя пользователя (любой регистр).
Пример: `readApp`

### Имя базы данных

Название базы, в которой будет создан пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read** — доступ только на чтение
* **readWrite** — чтение и изменение данных
* **dbOwner** — полный контроль над базой данных

---

## 4. Параметры модификации пользователя

### Имя пользователя

Необходимо выбрать существующего пользователя.
Если список пуст, требуется предварительно создать пользователя.

### Имя базы данных

База данных, к которой относится пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read**
* **readWrite**
* **dbOwner**

---

## 5. Параметры удаления пользователя

### Имя пользователя

Выберите пользователя из списка для удаления.

---

## 6. Выходные параметры

После успешного развертывания кластера платформа возвращает ключевые параметры.

### internalConnect

Внутренний эндпоинт для подключения к кластеру из сервисов, работающих в той же сети.
Используется для внутренних интеграций и системных сервисов.

### externalConnect

Внешний FQDN для подключения к кластеру извне.
Порт подключения — **27017**.

---

## 7. Пример подключения

Перед подключением необходимо установить **mongosh**.

Команда подключения к базе данных:

```
mongosh "mongodb://<username>:<password>@<endpoint_db>:27017/<dbName>"
```

Где:

* `<username>` — имя пользователя
* `<password>` — пароль
* `<endpoint_db>` — internalConnect или externalConnect
* `<dbName>` — имя базы данных

## 8. Дополнительная информация

Сейчас соединение с базой работает без шифрования, и доступ к кластеру осуществляется только по логину и паролю.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 37 - kind: instance - action: create - params: - - id: 487 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `2`' - sort: 10 - - id: 588 - code: resourceMemory - data_type: integer > 0 - required: true - minvalue: 1000 - descr: 'Пример: `2048`' - - id: 589 - code: resourceCPU - data_type: integer > 0 - required: true - descr: 'Пример: `1000`' - - id: 590 - code: resourceDisk - data_type: integer > 0 - required: true - descr: 'Пример: `20`' - - id: 595 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 645 - code: needExternalAddressMaster - data_type: string - required: true - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`' - - id: 646 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - - name: create_user - id: 198 - kind: subresource - action: create - subresource: user - params: - - id: 635 - code: username - data_type: string - required: true - - id: 636 - code: dbName - data_type: string - required: true - - id: 643 - code: role - data_type: string - required: true - value_list: - - dbOwner - - read - - readWrite - - name: delete - id: 190 - kind: instance - action: delete - params: [] - - name: delete_user - id: 199 - kind: subresource - action: delete - subresource: user - params: - - id: 644 - code: username - data_type: string - required: true - - name: modify_user - id: 200 - kind: subresource - action: modify - subresource: user - params: - - id: 640 - code: username - data_type: string - required: true - - id: 641 - code: dbName - data_type: string - required: true - - id: 642 - code: role - data_type: string - required: true - value_list: - - dbOwner - - read - - readWrite - - name: resume - id: 196 - kind: instance - action: resume - params: [] - - name: suspend - id: 194 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/93_rabbitmq.yaml b/generated/prod/resources_yaml/93_rabbitmq.yaml deleted file mode 100644 index 4fbf1cc..0000000 --- a/generated/prod/resources_yaml/93_rabbitmq.yaml +++ /dev/null @@ -1,180 +0,0 @@ -name: rabbitmq -service_id: 93 -service_display_name: RabbitMQ -service_short_name: rabbitmq -service_man: '# Инструкция по развертыванию RabbitMQ через платформу

---
## 1. Общая информация
RabbitMQ — это брокер сообщений с открытым исходным кодом, который обеспечивает надёжную доставку сообщений между приложениями.
Позволяет надёжно передавать сообщения между сервисами и системами, интегрироваться с внешними решениями и использовать как внутренние, так и защищённые TLS-подключения. Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание кластера
- **modify** — Изменение параметров кластера
- **delete** — Удаление кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера


---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса RabbitMQ:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество реплик в кластере RabbitMQ. При значении больше 1 создаётся кластер с репликацией для обеспечения высокой доступности.
Пример: `1` (single node) или `3` (кластер с репликацией)

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных RabbitMQ в гигабайтах. Пример: `50`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-узлу. При включении создаётся Service типа LoadBalancer и настраивается VIP на порту 5672.
Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`


---
## 3. Модификация кластера
Операция **modify** позволяет изменить параметры существующего кластера RabbitMQ.

**Изменяемые параметры:**
* **Квота (megabyte) памяти пода** — можно увеличить или уменьшить
* **Квота (millicore) ядра пода** — можно увеличить или уменьшить
* **Размер (gigabyte) диска для базы данных** — можно только увеличить (уменьшение не поддерживается)
* **Количество узлов в сети** — можно только увеличить (уменьшение не поддерживается)
* **Выделяет внешний IP для доступа к master** — можно включить или выключить
* **Имя ipSpace для публикации внешнего IP master** — можно изменить при включенном внешнем IP

**Ограничения:**
* Уменьшение размера диска не поддерживается
* Уменьшение количества реплик не поддерживается

---
## 4. Выходные параметры
После успешного развертывания ресурса RabbitMQ платформа возвращает ряд параметров в разделе "Поля состояния (сгенерированные значения)":

**clusterDomain**
Домен кластера Kubernetes, в котором развернут RabbitMQ.
Пример: `cluster.local`

**inernalConnect**
Внутренние эндпоинты для подключения к кластеру RabbitMQ из других сервисов, развернутых внутри той же сети.
Содержит:
* **master** — FQDN для подключения к кластеру. Пример: `rabbitmqk8s.{namespace}.svc.{clusterDomain}`

**externalConnect**
Внешние эндпоинты для подключения к кластеру RabbitMQ извне.
Содержит объекты с полями:
* **admin** — доступ к веб-интерфейсу управления:
* `fqdn` — полное доменное имя для веб-интерфейса. Пример: `admin.{namespace}.{domain}`
* `ip` — IP-адрес
* **master** — доступ к AMQP протоколу (если включен внешний IP):
* `fqdn` — полное доменное имя для AMQP. Пример: `write.{namespace}.{domain}`
* `ip` — IP-адрес

**monitoring**
Информация о дашбордах мониторинга:
* **allDashboards** — URL для доступа ко всем дашбордам Grafana

Для подключения используются следующие порты:

* **5672** — AMQP протокол (внутренний и внешний доступ, если включен внешний IP)
* **15672** — веб-интерфейс управления (доступен через Ingress по HTTPS)

**Учётные данные**
Данные для подключения к RabbitMQ доступны в разделе "Учётные данные":
* **adminUser** — имя пользователя администратора
* **adminPass** — пароль администратора


---
## 5. Примеры подключения через консоль (rabbitmqadmin)

### Работа с очередями через rabbitmqadmin

Для работы с RabbitMQ через консоль используется утилита `rabbitmqadmin`. Установите её или используйте образ с предустановленной утилитой.

Задайте переменные окружения с учётными данными:

```bash
export RABBITMQ_USERNAME=<adminUser>
export RABBITMQ_PASSWORD=<adminPass>
export RABBIT_HOST=<host>
```

Где:
* `<adminUser>` и `<adminPass>` — учётные данные из раздела "Учётные данные"
* `<host>` — адрес для подключения:
* Для внешнего подключения: `externalConnect.admin.fqdn` или `externalConnect.master.fqdn`

**Создание очереди:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
declare queue name=healthcheck durable=false
```

**Листинг очередей:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
list queues
```

**Отправка сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
publish exchange=amq.default routing_key=healthcheck payload="ping-$(date +%s)"
```

**Чтение сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
get queue=healthcheck ackmode=ack_requeue_false
```

---
## 6. Дополнительная информация
Для подключения к кластеру RabbitMQ используйте полученные эндпоинты из раздела "Поля состояния (сгенерированные значения)" и учётные данные из раздела "Учётные данные".

Веб-интерфейс управления доступен по адресу, указанному в параметре `externalConnect.admin.fqdn` через HTTPS.

Для внутреннего подключения используйте адрес из `inernalConnect.master` на порту 5672.

---' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 38 - kind: instance - action: create - params: - - id: 116 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 4000 - minvalue: 500 - descr: 'Пример: `2000`' - sort: 20 - is_modifiable: true - - id: 117 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1124" - maxvalue: 8192 - minvalue: 512 - descr: 'Пример: `2048`' - sort: 30 - is_modifiable: true - - id: 118 - code: resourceDisk - data_type: integer > 0 - required: true - default: "30" - maxvalue: 999 - minvalue: 5 - descr: 'Пример: `20`' - sort: 40 - is_modifiable: true - - id: 119 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 224 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - sort: 50 - is_modifiable: true - - id: 225 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`' - sort: 60 - is_modifiable: true - - id: 543 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - is_modifiable: true - - name: delete - id: 39 - kind: instance - action: delete - params: [] - - name: modify - id: 106 - kind: instance - action: modify - params: - - id: 304 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 4000 - minvalue: 500 - descr: 'Пример: `2000`' - sort: 10 - - id: 305 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 512 - descr: 'Пример: `2048`' - sort: 20 - - id: 306 - code: resourceDisk - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `20`' - sort: 10 - - id: 307 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - sort: 40 - - id: 308 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к master - sort: 50 - - id: 309 - code: needExternalAddressSlave - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к slave - sort: 60 - - id: 545 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - - id: 546 - code: ipSpaceNameSlave - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - - name: resume - id: 117 - kind: instance - action: resume - params: [] - - name: suspend - id: 116 - kind: instance - action: suspend - man: Пока не работает из за того что RabbitmqCluster нельзя занулить - params: [] diff --git a/generated/prod/resources_yaml/94_lucee.yaml b/generated/prod/resources_yaml/94_lucee.yaml deleted file mode 100644 index bf953fc..0000000 --- a/generated/prod/resources_yaml/94_lucee.yaml +++ /dev/null @@ -1,217 +0,0 @@ -name: lucee -service_id: 94 -service_display_name: Lucee -service_short_name: lucee -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 49 - kind: instance - action: create - params: - - id: 103 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 104 - code: gitPath - data_type: string - required: true - default: https://github.com/xahys/testlucee - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 60 - is_modifiable: true - - id: 105 - code: jsonEnv - data_type: json - required: false - default: '{ "param": "value" }' - maxlength: 2048 - descr: Здесь вы можете задать переменные среды в формате KEY=VALUE. Они будут доступны внутри вашего приложения. - sort: 70 - is_modifiable: true - - id: 106 - code: resourceCPU - data_type: integer > 0 - required: true - default: "300" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - man: Квота ядра пода (milicores) - sort: 30 - is_modifiable: true - - id: 107 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 108 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 132 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код - man: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код - sort: 80 - is_modifiable: true - - id: 139 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 50 - is_modifiable: true - - id: 263 - code: appVersion - data_type: string - required: true - default: "5.4" - value_list: - - "5.4" - - "6.0" - regex: ^\d+(\.\d+){1,2}(-[a-zA-Z0-9\.]+)?$ - descr: Версия Lucee - sort: 90 - is_modifiable: true - - name: delete - id: 50 - kind: instance - action: delete - params: [] - - name: modify - id: 55 - kind: instance - action: modify - man: Если CFS оставить пустым, то при запуске джобы берётся параметр из instanceData - params: - - id: 133 - code: gitPath - data_type: string - required: false - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 50 - - id: 134 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. - man: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. - sort: 60 - - id: 135 - code: jsonEnv - data_type: json - required: false - maxlength: 2048 - descr: Массив переменных, будут переданы в env приложения - man: Массив переменных, будут переданы в env приложения - sort: 40 - - id: 136 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) 1000Mili = 1 ядро - man: Квота ядра пода (Указывается в mili) - sort: 10 - - id: 137 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 20 - - id: 138 - code: resourceInstances - data_type: integer > 0 - required: false - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 30 - - id: 264 - code: appVersion - data_type: string - required: true - default: "5.4" - value_list: - - "5.4" - - "6.0" - regex: ^\d+(\.\d+){1,2}(-[a-zA-Z0-9\.]+)?$ - sort: 70 - - name: redeploy - id: 53 - kind: action - action: redeploy - params: - - id: 257 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: restart - id: 163 - kind: action - action: restart - params: [] - - name: resume - id: 95 - kind: instance - action: resume - params: [] - - name: suspend - id: 96 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/95_nodejs.yaml b/generated/prod/resources_yaml/95_nodejs.yaml deleted file mode 100644 index d2e7e61..0000000 --- a/generated/prod/resources_yaml/95_nodejs.yaml +++ /dev/null @@ -1,215 +0,0 @@ -name: nodejs -service_id: 95 -service_display_name: NodeJS -service_short_name: nodejs -service_man: Развертывает контейнер в k8s кластере с node:16, который можно использовать для запуска своих приложений.
Приложение должно быть доступно по ссылки в git репозитории, которая является входным параметром. -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 58 - kind: instance - action: create - params: - - id: 149 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Наименование поддомена, будет добавлено в nodejs.dev.nubes.ru - sort: 10 - - id: 150 - code: gitPath - data_type: string - required: true - default: https://github.com/xahys/testnode.git - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 60 - is_modifiable: true - - id: 151 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет - man: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. Если оставить пустым, healtcheck'а не будет - sort: 80 - is_modifiable: true - - id: 152 - code: jsonEnv - data_type: json - required: false - descr: Массив переменных, будут переданы в env приложения - man: Массив переменных, будут переданы в env приложения - sort: 70 - is_modifiable: true - - id: 153 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores). 1000Mili = 1 Ядро - man: Квота ядра пода (milicores). 1000Mili = 1 Ядро - sort: 30 - is_modifiable: true - - id: 154 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1024" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 155 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 50 - is_modifiable: true - - id: 156 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 20 - - id: 270 - code: appVersion - data_type: string - required: true - default: "23" - value_list: - - "18" - - "20" - - "22" - - "23" - regex: ^(\d){2}$ - descr: Версия приложения - sort: 90 - is_modifiable: true - - name: delete - id: 61 - kind: instance - action: delete - params: [] - - name: modify - id: 59 - kind: instance - action: modify - params: - - id: 157 - code: gitPath - data_type: string - required: false - descr: Путь до Git, который будет webroot для сайта - man: Путь до Git, который будет webroot для сайта - sort: 50 - - id: 158 - code: healthPath - data_type: string - required: false - descr: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. - man: Путь до healtcheck для запуска пода в Kubernetes, который отдаст 200 код. - sort: 60 - - id: 159 - code: jsonEnv - data_type: json - required: false - maxlength: 2048 - descr: Массив переменных, будут переданы в env приложения - man: Массив переменных, будут переданы в env приложения - sort: 40 - - id: 160 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) 1000Mili = 1 ядро - man: Квота ядра пода (Указывается в mili) 1000Mili = 1 ядро - sort: 10 - - id: 161 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 20 - - id: 162 - code: resourceInstances - data_type: integer > 0 - required: false - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 30 - - id: 271 - code: appVersion - data_type: string - required: true - default: "23" - value_list: - - "18" - - "20" - - "22" - - "23" - regex: ^(\d){2}$ - descr: Версия приложения - man: Версия приложения - sort: 70 - - name: redeploy - id: 60 - kind: action - action: redeploy - params: - - id: 258 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: resume - id: 121 - kind: instance - action: resume - params: [] - - name: suspend - id: 120 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/96_pgadmin.yaml b/generated/prod/resources_yaml/96_pgadmin.yaml deleted file mode 100644 index 5b1ff7a..0000000 --- a/generated/prod/resources_yaml/96_pgadmin.yaml +++ /dev/null @@ -1,158 +0,0 @@ -name: pgadmin -service_id: 96 -service_display_name: pgAdmin -service_short_name: pgadmin -service_man: Инструмент с графическим интерфейсом для управления базами данных PostgreSQL -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 62 - kind: instance - action: create - params: - - id: 164 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 165 - code: resourceCPU - data_type: integer > 0 - required: true - default: "200" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores). 1000Mili = 1 Ядро - man: Квота ядра пода (milicores). 1000Mili = 1 Ядро - sort: 30 - is_modifiable: true - - id: 166 - code: resourceMemory - data_type: integer > 0 - required: true - default: "256" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 167 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 169 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 170 - code: login - data_type: string - required: true - regex: ^([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)$ - maxlength: 255 - minlength: 3 - descr: Логин для подключения к pgAdmin, в формате email (login@email.net) - man: Логин для подключения к pgAdmin, в формате email (login@email.net) - sort: 60 - - id: 171 - code: password - data_type: string - required: true - descr: Пароль для подключения к pgAdmin - man: Пароль для подключения к pgAdmin - sort: 70 - is_sensitive: true - - name: delete - id: 63 - kind: instance - action: delete - params: [] - - name: modify - id: 64 - kind: instance - action: modify - params: - - id: 172 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - - id: 173 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - - id: 174 - code: resourceDisk - data_type: integer > 0 - required: false - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - - name: redeploy - id: 65 - kind: action - action: redeploy - params: - - id: 277 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: resume - id: 123 - kind: instance - action: resume - params: [] - - name: suspend - id: 122 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/97_nodered.yaml b/generated/prod/resources_yaml/97_nodered.yaml deleted file mode 100644 index 4edaed8..0000000 --- a/generated/prod/resources_yaml/97_nodered.yaml +++ /dev/null @@ -1,91 +0,0 @@ -name: nodered -service_id: 97 -service_display_name: NodeRed -service_short_name: nodered -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 72 - kind: instance - action: create - params: - - id: 193 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 30 - - id: 194 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - sort: 40 - - id: 195 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 60 - - id: 196 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 197 - code: domain - data_type: string - required: true - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - man: Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - sort: 10 - - id: 323 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 50 - - name: delete - id: 73 - kind: instance - action: delete - params: [] diff --git a/generated/prod/resources_yaml/98_http.yaml b/generated/prod/resources_yaml/98_http.yaml deleted file mode 100644 index 58a9db9..0000000 --- a/generated/prod/resources_yaml/98_http.yaml +++ /dev/null @@ -1,150 +0,0 @@ -name: http -service_id: 98 -service_display_name: Простой HTTP контейнер -service_short_name: http -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 77 - kind: instance - action: create - params: - - id: 212 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 213 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) - man: Квота ядра пода (Указывается в mili) - sort: 30 - is_modifiable: true - - id: 214 - code: resourceMemory - data_type: integer > 0 - required: true - default: "200" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 40 - is_modifiable: true - - id: 215 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество реплик приложения. Трафик будет распределяться между подами в режиме Round-Robin - sort: 50 - is_modifiable: true - - id: 216 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 217 - code: registryPath - data_type: string - required: true - default: nexus-sa.tst.nubes.ru/docker-nubes/jolt - descr: Путь до image, который будет установлен как deployment - man: Путь до image, который будет установлен как deployment - sort: 60 - - id: 241 - code: jsonEnv - data_type: json - required: false - default: '{"param": "value"}' - descr: Массив переменных, будут переданы в env приложения - man: Массив переменных, будут переданы в env приложения - sort: 70 - - name: delete - id: 78 - kind: instance - action: delete - params: [] - - name: modify - id: 81 - kind: instance - action: modify - params: - - id: 218 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 4000 - minvalue: 100 - - id: 219 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 128 - - id: 220 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - - name: redeploy - id: 79 - kind: action - action: redeploy - params: - - id: 272 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 10 - - name: resume - id: 130 - kind: instance - action: resume - params: [] - - name: suspend - id: 131 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/99_gitea.yaml b/generated/prod/resources_yaml/99_gitea.yaml deleted file mode 100644 index 87f9cb9..0000000 --- a/generated/prod/resources_yaml/99_gitea.yaml +++ /dev/null @@ -1,153 +0,0 @@ -name: gitea -service_id: 99 -service_display_name: Gitea -service_short_name: gitea -service_man: Развертывает сервис контроля версий Gitea
Зависит от сервиса postgresql который должен быть развернут заранее. -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 82 - kind: instance - action: create - params: - - id: 232 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 300 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 40 - is_modifiable: true - - id: 233 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 256 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 50 - is_modifiable: true - - id: 234 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 60 - is_modifiable: true - - id: 235 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 70 - is_modifiable: true - - id: 237 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 20 - - id: 238 - code: psqlUid - data_type: uuid - required: true - ref_svc_id: 90 - descr: UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - man: UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - sort: 10 - - name: delete - id: 83 - kind: instance - action: delete - params: [] - - name: modify - id: 91 - kind: instance - action: modify - params: - - id: 259 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 10 - - id: 260 - code: resourceMemory - data_type: integer > 0 - required: true - default: "128" - maxvalue: 8192 - minvalue: 256 - descr: Квота памяти пода (Указывается в Megabytes) - sort: 20 - - id: 261 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 30 - - id: 262 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 40 - - name: resume - id: 127 - kind: instance - action: resume - params: [] - - name: suspend - id: 126 - kind: instance - action: suspend - params: [] diff --git a/generated/prod/resources_yaml/embed.go b/generated/prod/resources_yaml/embed.go deleted file mode 100644 index 72e3ff2..0000000 --- a/generated/prod/resources_yaml/embed.go +++ /dev/null @@ -1,8 +0,0 @@ -package resources_yaml - -import "embed" - -// Files embeds unified service YAML specs for provider runtime lookup. -// -//go:embed *.yaml -var Files embed.FS diff --git a/generated/test/analyze_deps.py b/generated/test/analyze_deps.py deleted file mode 100644 index 8739d5f..0000000 --- a/generated/test/analyze_deps.py +++ /dev/null @@ -1,38 +0,0 @@ -import glob, yaml, json - -yaml_dir = "/home/naeel/terra/terraform/devops/profiles/test/generated/resources_yaml" -missing_ids = {100,110,113,114,115,116,117,119,120,149,1,20,23,27,29,2,32,50,81,82,88,89,91,92,96,97,98,99} - -results = [] -for f in sorted(glob.glob(yaml_dir + "/*.yaml")): - data = yaml.safe_load(open(f)) - sid = data.get("service_id") - if sid not in missing_ids: - continue - name = data.get("name","") - disp = data.get("service_display_name","") - ops = data.get("operations", []) - ref_params = [] - req_params = [] - for op in ops: - if op.get("kind") == "instance" and op.get("action") == "create": - for p in op.get("params", []): - code = p.get("code","") - req = p.get("required", False) - ref_svc = p.get("ref_service_id","") - if ref_svc: - ref_params.append(code + "(svc=" + str(ref_svc) + ")") - elif req: - req_params.append(code) - results.append({ - "serviceId": sid, - "name": name, - "display": disp, - "deps": ref_params, - "required_params": req_params, - }) - -for r in results: - dep_str = str(r["deps"]) if r["deps"] else "none" - req_str = str(r["required_params"]) if r["required_params"] else "[]" - print("[" + str(r["serviceId"]).rjust(3) + "] " + r["name"].ljust(25) + " deps=" + dep_str + " required=" + req_str) diff --git a/generated/test/collect_service_params.py b/generated/test/collect_service_params.py deleted file mode 100644 index 746ce6b..0000000 --- a/generated/test/collect_service_params.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python3 -""" -Универсальный сборщик state_params для сервисов тест-стенда. -Создаёт инстанс, снимает параметры, суспендит. - -Использование: - python3 collect_service_params.py [display_name] -""" - -import json, sys, time, urllib.request, urllib.error, urllib.parse, os, yaml, html - -API = "https://deck-api-test.ngcloud.ru/api/v1/index.cfm" -TOKEN = open("/home/naeel/terra/terraform/secrets/test.token").read().strip() -OUT_DIR = "/home/naeel/terra/terraform/devops/profiles/test/generated/output_inventory" - -HEADERS = { - "Authorization": f"Bearer {TOKEN}", - "Content-Type": "application/json", -} - -# Минимальные значения по умолчанию для стандартных параметров -PARAM_DEFAULTS = { - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "resourceCPU": "1000", - "resourceMemory": "1024", - "resourceDisk": "10", - "resourceInstances": "1", - "resourceInstancesShards": "1", - "needExternalAddressMaster": "false", - "needExternalAddressSlave": "false", - "needCreateKeeper": "false", - "autoScale": "false", - "durationMs": "10000", - "failAtStart": "false", - "failInProgress": "false", - "domain": "web-test-stand", - "appVersion": "latest", - "jsonEnv": "{}", - "login": "admin@ngcloud.ru", - "password": "Admin123!", - "gitPath": "https://github.com/Foxyhhd/Baldurs-Gate-test.git", - # Для dummy - "mapExample": "{}", - "jsonExample": "{}", - "yamlExample": "", - "bodymessage": "", - "whereFail": "1", -} - -# Переопределения для конкретных сервисов {service_id: {code: value}} -SVC_PARAM_OVERRIDES = { - 97: {"domain": "inv-nodered"}, - 110: {"zoneEmail": "admin@ngcloud.ru", "zoneName": "inv-test.ngcloud.ru"}, - 117: {"domain": "inv-nifi"}, - 99: {"domain": "inv-gitea"}, - 82: {"domain": "inv-harbor"}, -} - -def req(method, path, body=None): - url = API + path - data = json.dumps(body).encode() if body is not None else None - r = urllib.request.Request(url, data=data, headers=HEADERS, method=method) - try: - with urllib.request.urlopen(r, timeout=30) as resp: - raw = resp.read() - loc = resp.headers.get("Location", "") - return json.loads(raw) if raw else {}, loc - except urllib.error.HTTPError as e: - raw = e.read() - print(f" HTTP {e.code} {method} {path}: {raw[:300]}") - return None, "" - -def get(path): - result, _ = req("GET", path) - return result - -def post(path, body): - return req("POST", path, body) - -def wait_op(op_uid, timeout=300): - deadline = time.time() + timeout - while time.time() < deadline: - data = get(f"/instanceOperations/{op_uid}?fields=dtFinish,isSuccessful,errorLog,isInProgress,isPending") - if data is None: - return False, "request error" - op = data.get("instanceOperation", data) - in_prog = op.get("isInProgress", True) - pending = op.get("isPending", True) - if not in_prog and not pending: - success = op.get("isSuccessful", False) - err = op.get("errorLog", "") - return success, err - time.sleep(5) - return False, "timeout" - -def create_instance(service_id, display_name): - print(f"\n=== Создаём инстанс: svc={service_id}, name={display_name} ===") - - # 0. Загружаем YAML чтобы знать code для каждого param_id - import glob as _glob - yaml_dir = "/home/naeel/terra/terraform/devops/profiles/test/generated/resources_yaml" - yaml_files = _glob.glob(yaml_dir + "/*.yaml") - param_id_to_code = {} - for yf in yaml_files: - ydata = yaml.safe_load(open(yf)) - if ydata.get("service_id") != service_id: - continue - for op in ydata.get("operations", []): - for p in op.get("params", []): - pid = p.get("id") - code = p.get("code", "") - if pid and code: - param_id_to_code[pid] = code - break - print(f" YAML param id→code map: {len(param_id_to_code)} entries") - # 1. Создаём инстанс - resp, loc = post("/instances", { - "serviceId": service_id, - "displayName": display_name, - "descr": "inventory-collector", - }) - if resp is None: - return None - if isinstance(resp, dict): - instance_uid = resp.get("instanceUid") - else: - instance_uid = None - if not instance_uid and loc: - instance_uid = loc.rstrip("/").split("/")[-1] - if not instance_uid: - print(f" ERR: нет instanceUid. resp={resp}, loc={loc}") - return None - print(f" instanceUid: {instance_uid}") - - # 2. Создаём операцию create - resp, loc = post("/instanceOperations", { - "instanceUid": instance_uid, - "operation": "create", - }) - if resp is None: - return None - op = resp.get("instanceOperation", resp) if isinstance(resp, dict) else {} - op_uid = op.get("instanceOperationUid") - if not op_uid and loc: - op_uid = loc.rstrip("/").split("/")[-1] - if not op_uid: - print(f" ERR: нет opUid. resp={resp}, loc={loc}") - return None - print(f" opUid: {op_uid}") - - # 3. Получаем cfsParams с ID - op_detail = get(f"/instanceOperations/{op_uid}?fields=cfsParams") - if op_detail is None: - return None - cfs_params = (op_detail.get("instanceOperation") or op_detail).get("cfsParams", []) - print(f" cfsParams count: {len(cfs_params)}") - for p in cfs_params: - code_display = p.get("svcOperationCfsParam") or p.get("code", "?") - print(f" id={p['svcOperationCfsParamId']} code={code_display} required={p.get('isRequired')} default={p.get('defaultValue')} paramValue={p.get('paramValue')}") - - # 4. Заполняем параметры (POST для КАЖДОГО — иначе /run ломается с GUID-ошибкой) - filled = 0 - for p in cfs_params: - param_id = p["svcOperationCfsParamId"] - # Получаем code: сначала из прямого поля API, потом из YAML-маппинга - code = p.get("svcOperationCfsParam") or param_id_to_code.get(param_id, p.get("code", "")) - current = p.get("paramValue") - default = p.get("defaultValue") - # Переопределения для конкретного сервиса имеют наивысший приоритет - overrides = SVC_PARAM_OVERRIDES.get(service_id, {}) - - # Определяем значение - # Пропускаем pre-populated невалидные значения ('""', пустые строки) - if current is not None and str(current) not in ('""', "''", ""): - value = str(current) - elif code in overrides: - value = overrides[code] - elif default is not None and str(default).strip() != "": - # HTML-unescape дефолтов (API может вернуть " и т.п.) - value = html.unescape(str(default)) - elif code in PARAM_DEFAULTS: - value = PARAM_DEFAULTS[code] - else: - value = "" # Отправляем пустую строку — сервер требует запись для каждого параметра - - resp2, loc2 = post("/instanceOperationCfsParams", { - "instanceOperationUid": op_uid, - "svcOperationCfsParamId": param_id, - "paramValue": value, - }) - if resp2 is not None and (loc2 or resp2 != {}): - filled += 1 - elif resp2 is None: - print(f" WARN: param id={param_id} code={code} не принят API (400/422), value={value!r}") - print(f" Заполнено параметров: {filled}") - - # 5. validate-cfs — GET (в HAR это GET, не POST; на test может вернуть 405 — терпим) - req("GET", f"/instanceOperations/{op_uid}/validate-cfs") - - # 6. Run - resp4, _ = post(f"/instanceOperations/{op_uid}/run", {}) - if resp4 is None: - print(" ERR: run вернул ошибку — сервис может быть сырым/нерабочим") - return instance_uid # возвращаем uid — state может быть частичным - print(" Операция запущена, ждём завершения...") - - # 7. Ждём - success, err = wait_op(op_uid, timeout=600) - if not success: - print(f" WARN: операция завершилась с ошибкой (сервис сырой?): {err[:200]}") - # Не прерываемся — возвращаем uid, state может содержать частичные данные - else: - print(" Создание завершено успешно!") - return instance_uid - -def collect_state(instance_uid): - detail = get(f"/instances/{instance_uid}?fields=instanceUid,displayName,serviceId,svc,state,explainedStatus") - if not detail: - return None - inst = detail.get("instance", {}) - state = inst.get("state", {}) or {} - return { - "uid": instance_uid, - "name": inst.get("displayName",""), - "serviceId": inst.get("serviceId"), - "svc_code": inst.get("svc",""), - "status": inst.get("explainedStatus",""), - "params": state.get("params",{}) or {}, - "out": state.get("out",{}) or {}, - "vault_keys": list((state.get("vault",{}) or {}).keys()), - } - -def suspend_instance(instance_uid): - print(f" Суспендим {instance_uid}...") - resp, loc = post("/instanceOperations", { - "instanceUid": instance_uid, - "operation": "suspend", - }) - if resp is None: - return - op = resp.get("instanceOperation", resp) if isinstance(resp, dict) else {} - op_uid = op.get("instanceOperationUid") - if not op_uid and loc: - op_uid = loc.rstrip("/").split("/")[-1] - if not op_uid: - return - post(f"/instanceOperations/{op_uid}/run", {}) - success, err = wait_op(op_uid, timeout=300) - if success: - print(" Suspended!") - else: - print(f" WARN suspend: {err}") - -def save_to_inventory(state_data): - svc_id = state_data["serviceId"] - safe = state_data["svc_code"].replace("/","_").replace(" ","_") - fname = os.path.join(OUT_DIR, f"svc_{svc_id}_{safe}.json") - - existing = {} - if os.path.exists(fname): - existing = json.load(open(fname)) - - instances = existing.get("instances", []) - # Не дублируем - uids = {i["uid"] for i in instances} - if state_data["uid"] not in uids: - instances.append(state_data) - - result = { - "serviceId": svc_id, - "svc_code": state_data["svc_code"], - "instances": instances, - } - with open(fname, "w") as f: - json.dump(result, f, indent=2, ensure_ascii=False) - print(f" Saved: {fname}") - - # Обновляем индекс - rebuild_index() - -def rebuild_index(): - import glob - index = [] - for f in sorted(glob.glob(os.path.join(OUT_DIR, "svc_*.json"))): - data = json.load(open(f)) - all_params = set() - all_out = set() - all_vault = set() - for item in data.get("instances", []): - all_params.update((item.get("params") or {}).keys()) - out = item.get("out") - all_out.update((out.keys() if isinstance(out, dict) else [])) - all_vault.update(item.get("vault_keys", [])) - index.append({ - "serviceId": data["serviceId"], - "svc_code": data["svc_code"], - "instance_count": len(data.get("instances", [])), - "state_params_keys": sorted(all_params), - "state_out_keys": sorted(all_out), - "vault_keys": sorted(all_vault), - }) - with open(os.path.join(OUT_DIR, "index.json"), "w") as f: - json.dump(index, f, indent=2, ensure_ascii=False) - -# ===== MAIN ===== -if __name__ == "__main__": - if len(sys.argv) < 2: - print("Usage: collect_service_params.py [display_name]") - sys.exit(1) - - service_id = int(sys.argv[1]) - display_name = sys.argv[2] if len(sys.argv) > 2 else f"inventory-svc{service_id}" - - instance_uid = create_instance(service_id, display_name) - if not instance_uid: - print("FAILED: не удалось создать инстанс") - sys.exit(1) - - # Небольшая пауза перед чтением state - time.sleep(3) - state = collect_state(instance_uid) - if state: - print(f"\n state_params keys: {list(state['params'].keys())}") - print(f" state_out keys: {list(state['out'].keys()) if isinstance(state['out'], dict) else '-'}") - print(f" vault keys: {state['vault_keys']}") - save_to_inventory(state) - else: - print("WARN: не удалось получить state") - - suspend_instance(instance_uid) - print("\nDone.") diff --git a/generated/test/docs/akhq.md b/generated/test/docs/akhq.md deleted file mode 100644 index b160ca3..0000000 --- a/generated/test/docs/akhq.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## MAN - -
-# Инструкция по развертыванию Apache Kafka через платформу

---
## 1. Общая информация
AKHQ — это веб-интерфейс для работы с кластерами Apache Kafka.
Позволяет просматривать топики, consumer group'ы, сообщения, ACL, схему безопасности, состояние брокеров и метаданные.
Поддерживает работу с несколькими кластерами Kafka одновременно, включая внутренние и внешние (TLS) подключения.

## Доступные операции
- **create** — Создание ресурса AKHQ
- **suspend** — Остановка ресурса
- **resume** — Возобновление работы ресурса
- **modify** — Модификация настроек
- **delete** — Удаление ресурса

---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса Kafka:

* **Кластер Kafka к которому нужно настроить подключение**
Для использования AKHQ необходимо предварительно развернуть сервис Kafka. Пример: `kafka-external`.

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество узлов для работы Akhq. Пример `2`

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `512`

* **Квота (millicore ) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `500`

* **Имя домена:**
Dns Имя по которому будет происходить обращение к сервису. Указать необходимо уникальное имя до . ( то есть если необходимо получить dns ui) Пример: `kafka-external`

---
## 4. Выходные параметры
После успешного развертывания ресурса Kafka платформа возвращает ряд параметров.
Ключевым из них является:

**connectionUrl**
Это полное доменное имя (FQDN), по которому будет доступен интерфейс AKHQ. После развёртывания подождите несколько минут — UI станет доступен по HTTPS, как только все сервисы полностью запустятся.

**Учетные данные**
Здесь представлены поля для ввода логина и пароля, с помощью которых вы сможете авторизоваться в сервисе.

---
## 5. Дополнительная информация
Учётные записи, созданные для работы с AKHQ, предоставляют доступ только для просмотра данных. Для управления Kafka, пожалуйста, используйте возможности личного кабинета.
--- -
diff --git a/generated/test/docs/akhq_example.md b/generated/test/docs/akhq_example.md deleted file mode 100644 index 5163b84..0000000 --- a/generated/test/docs/akhq_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Copy-ready manifest (`akhq_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_akhq" "baza" { - resource_realm = "TODO" # Выбрать платформу из списка - domain = "TODO" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - kafka_uid = "TODO" # Выбрать кластер из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_memory = 512 # Пример: `1024` - resource_cpu = 500 # Пример: `1000` - resource_instances = 1 -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_akhq.baza.state_params["имя_ключа"] -nubes_akhq.baza.state_out["имя_ключа"] -nubes_akhq.baza.state_params_flat["имя_ключа"] -nubes_akhq.baza.state_out_flat["имя_ключа"] -nubes_akhq.baza.vault_secrets["имя_ключа"] -nubes_akhq.baza.vault_url -nubes_akhq.baza.vault_user_path -nubes_akhq.baza.vault_fields -``` diff --git a/generated/test/docs/akhq_ops.md b/generated/test/docs/akhq_ops.md deleted file mode 100644 index 9e4364f..0000000 --- a/generated/test/docs/akhq_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](akhq_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](akhq_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/test/docs/akhq_outputs.md b/generated/test/docs/akhq_outputs.md deleted file mode 100644 index 22405f5..0000000 --- a/generated/test/docs/akhq_outputs.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` - -### `vault_secrets` ключи - -- `vault_secrets["pass"]` -- `vault_secrets["user"]` - diff --git a/generated/test/docs/akhq_params.md b/generated/test/docs/akhq_params.md deleted file mode 100644 index b419cf6..0000000 --- a/generated/test/docs/akhq_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Parameters - -- [Create params](akhq_params_create.md) -- [Modify params](akhq_params_modify.md) diff --git a/generated/test/docs/akhq_params_create.md b/generated/test/docs/akhq_params_create.md deleted file mode 100644 index 687ca12..0000000 --- a/generated/test/docs/akhq_params_create.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
550resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
553domainstringЕсли будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
555kafka_uiduuidВыбрать кластер из спискаref_svc_id=116
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
551resource_memoryinteger512Пример: `1024`minvalue=512
552resource_cpuinteger500Пример: `1000`minvalue=500
554resource_instancesinteger1minvalue=1
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/akhq_params_modify.md b/generated/test/docs/akhq_params_modify.md deleted file mode 100644 index 1ba2657..0000000 --- a/generated/test/docs/akhq_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_akhq - -Service ID: `119` - -Service Name: Akhq - -[Manual](akhq.md) | [Create params](akhq_params_create.md) | [Modify params](akhq_params_modify.md) | [Output params](akhq_outputs.md) | [Operations](akhq_ops.md) | [Example](akhq_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
565kafka_uiduuidВыбрать кластер из спискаref_svc_id=116
diff --git a/generated/test/docs/clickhouse.md b/generated/test/docs/clickhouse.md deleted file mode 100644 index b496cff..0000000 --- a/generated/test/docs/clickhouse.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_clickhouse - -Service ID: `120` - -Service Name: ClickHouse - -[Manual](clickhouse.md) | [Create params](clickhouse_params_create.md) | [Modify params](clickhouse_params_modify.md) | [Output params](clickhouse_outputs.md) | [Operations](clickhouse_ops.md) | [Example](clickhouse_example.md) - -## MAN - -
-# Инструкция по управлению кластерами и пользователями ClickHouse

---

## Общая информация

ClickHouse — это колоночная система управления базами данных, предназначенная для обработки аналитических запросов в реальном времени. Платформа позволяет создавать, удалять, приостанавливать и возобновлять кластеры ClickHouse, а также управлять базами данных и пользователями.

Кластер создаётся через оператор Altinity (`https://github.com/Altinity/clickhouse-operator`) в ресурсной платформе типа `k8s`

Кластеры могут создаваться шардированными с произвольным количеством реплик. Для обеспечения отказоустойчивости и координации обязательно включение параметра `Создать ClickHouse-Keeper`.

Кластера создаются с обязательным бекапом. Для этого необходимо предварительно создать услугу `S3 Object Storage`.
---

## Доступные операции

* **create** — Создание кластера
* **delete** — Удаление кластера
* **suspend** — Приостановка работы кластера
* **resume** — Возобновление работы кластера
* **create_database** — Создание базы данных
* **delete_database** — Удаление базы данных
* **create_user** — Создание пользователя и настройка прав доступа к базе данных
* **delete_user** — Удаление пользователя

## Процесс создания и первого подключения

1. Выполнить операцию `create` - будет создан кластер
2. Выполнить операцию `create_database` - будет создана база данных
3. Выполнить операцию `create_user` - будет создан пользователь (выбрать доступ подключения к БД, созданной в п.2)

## Примеры подключения

### Подключение через HTTP-интерфейс

```bash
# Проверка доступности кластера
curl "http://<username>:<password>@<host>:8123/" -d "SELECT 1"

# Выполнение запроса
curl "http://<username>:<password>@<host>:8123/" -d "SHOW DATABASES"
```

## Простые кейсы
*Создать БД и обычной таблицы*
```clickhouse
CREATE TABLE database.table
(
id UInt64,
value String
)
ENGINE = MergeTree()
ORDER BY id;

INSERT INTO database.table SELECT number, toString(number) FROM numbers(10000000);

SELECT count() FROM database.table;
```
Базы и таблицы не реплицируются без специального ключа (`ON CLUSTER 'clickhousek8s'`)
В случае создания в стиле, описанным выше, необходимо будет выполнять действия на всех шардах/репликах


*Создание БД и шардированной таблицы*
```clickhouse
CREATE TABLE database.localUsers
(
id UInt64,
value String
)
ENGINE = MergeTree()
ORDER BY id;

CREATE TABLE database.shardedTable
AS localUsers
ENGINE = Distributed('clickhousek8s', 'database', 'localUsers', id);

INSERT INTO shardedTable SELECT number, toString(number) FROM numbers(10000000);

SELECT count() FROM shardedTable;
```
Важный момент - в данном примере таблицы придётся также выполнять на всех нодах ClickHouse

*Создание реплицируемой и шардированной таблицы*
```clickhouse
CREATE TABLE IF NOT EXISTS database.localUsers ON cluster 'clickhousek8s'
(
user_id UInt64,
name String,
email String
)
ENGINE = ReplicatedMergeTree(
'/clickhouse/tables/{shard}/localUsers',
'{replica}'
)
ORDER BY user_id;

CREATE TABLE IF NOT EXISTS database.users ON cluster 'clickhousek8s'
AS database.localUsers
ENGINE = Distributed('clickhousek8s', 'database', 'localUsers', rand());

INSERT INTO database.users VALUES (1, 'Alice', 'alice@example.com');
INSERT INTO database.users VALUES (2, 'Bob', 'bob@example.com');
INSERT INTO database.users VALUES (3, 'Charlie', 'charlie@example.com');
INSERT INTO database.users VALUES (4, 'David', 'david@example.com');
INSERT INTO database.users VALUES (5, 'Gosha', 'gosha@example.com');
INSERT INTO database.users VALUES (6, 'Eve', 'eve@example.com');
INSERT INTO database.users VALUES (7, 'Frank', 'frank@example.com');
INSERT INTO database.users VALUES (8, 'Grace', 'grace@example.com');
INSERT INTO database.users VALUES (9, 'Hannah', 'hannah@example.com');
INSERT INTO database.users VALUES (10, 'Ivan', 'ivan@example.com');

SELECT * FROM database.localUsers;
SELECT * FROM database.users;

SELECT COUNT(*) AS total_users FROM database.users;
SELECT COUNT(*) AS total_users_local FROM database.localUsers;
``` -
diff --git a/generated/test/docs/clickhouse_database.md b/generated/test/docs/clickhouse_database.md deleted file mode 100644 index 3c6c66d..0000000 --- a/generated/test/docs/clickhouse_database.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_clickhouse_database - -Service: `nubes_clickhouse` (ID: 120) - -[ClickHouse (основной)](clickhouse.md) | [Operations](clickhouse_ops.md) | [Database](clickhouse_database.md) | [Example](clickhouse_database_example.md) - -## Create params - -**Обязательные параметры** - -None. - -**Параметры со значением по умолчанию** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
600db_namestringdb01Пример: `db01`regex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
602db_namestringВСЕ ДАННЫЕ ВНУТРИ БД БУДУТ УДАЛЕНЫ
diff --git a/generated/test/docs/clickhouse_database_example.md b/generated/test/docs/clickhouse_database_example.md deleted file mode 100644 index b1a9e74..0000000 --- a/generated/test/docs/clickhouse_database_example.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_clickhouse_database — Example - -Service: `nubes_clickhouse` (ID: 120) - -[ClickHouse (основной)](clickhouse.md) | [Operations](clickhouse_ops.md) | [Database](clickhouse_database.md) | [Example](clickhouse_database_example.md) - -## Copy-ready manifest (`clickhouse_database_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_clickhouse должен быть создан заранее -# resource "nubes_clickhouse" "baza" { ... } - -resource "nubes_clickhouse_database" "example" { - clickhouse_id = nubes_clickhouse.baza.id - - # Параметры со значением по умолчанию - db_name = "db01" # Пример: `db01` -} -``` diff --git a/generated/test/docs/clickhouse_example.md b/generated/test/docs/clickhouse_example.md deleted file mode 100644 index b12740e..0000000 --- a/generated/test/docs/clickhouse_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_clickhouse - -Service ID: `120` - -Service Name: ClickHouse - -[Manual](clickhouse.md) | [Create params](clickhouse_params_create.md) | [Modify params](clickhouse_params_modify.md) | [Output params](clickhouse_outputs.md) | [Operations](clickhouse_ops.md) | [Example](clickhouse_example.md) - -## Copy-ready manifest (`clickhouse_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_clickhouse" "baza" { - startup_configuration = "TODO" - cluster_configuration = "TODO" - access_configuration = "TODO" - clickhouse_keeper_configuration = "TODO" - clickhouse_configuration = "TODO" - backup_configuration = "TODO" - autoscale_configuration = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_clickhouse.baza.state_params["имя_ключа"] -nubes_clickhouse.baza.state_out["имя_ключа"] -nubes_clickhouse.baza.state_params_flat["имя_ключа"] -nubes_clickhouse.baza.state_out_flat["имя_ключа"] -nubes_clickhouse.baza.vault_secrets["имя_ключа"] -nubes_clickhouse.baza.vault_url -nubes_clickhouse.baza.vault_user_path -nubes_clickhouse.baza.vault_fields -``` diff --git a/generated/test/docs/clickhouse_ops.md b/generated/test/docs/clickhouse_ops.md deleted file mode 100644 index a2c10d2..0000000 --- a/generated/test/docs/clickhouse_ops.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_clickhouse - -Service ID: `120` - -Service Name: ClickHouse - -[Manual](clickhouse.md) | [Create params](clickhouse_params_create.md) | [Modify params](clickhouse_params_modify.md) | [Output params](clickhouse_outputs.md) | [Operations](clickhouse_ops.md) | [Example](clickhouse_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](clickhouse_params_create.md) -- `create_database` — База данных создаётся на всех репликах кластера ClickHouse. См. [nubes_clickhouse_database](clickhouse_database.md) -- `create_user` — . См. [nubes_clickhouse_user](clickhouse_user.md) -- `delete` — Удаление возможно только после остановки сервиса через операцию `suspend` После выполнения операции необходимо выждать определенное кол-во времени -- `delete_database` — Необратимое действие!!! Трижды подумай, заблокируй телефон тимлида и не выполняй это действие. См. [nubes_clickhouse_database](clickhouse_database.md) -- `delete_user` — . См. [nubes_clickhouse_user](clickhouse_user.md) -- `modify` — Изменение кластера. Параметры: [Modify params](clickhouse_params_modify.md) -- `reconcile` -- `resume` -- `suspend` — Операция приводит к удалению всех подов Persistent Volume остаются нетронутыми diff --git a/generated/test/docs/clickhouse_outputs.md b/generated/test/docs/clickhouse_outputs.md deleted file mode 100644 index 82ea3b7..0000000 --- a/generated/test/docs/clickhouse_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_clickhouse - -Service ID: `120` - -Service Name: ClickHouse - -[Manual](clickhouse.md) | [Create params](clickhouse_params_create.md) | [Modify params](clickhouse_params_modify.md) | [Output params](clickhouse_outputs.md) | [Operations](clickhouse_ops.md) | [Example](clickhouse_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/clickhouse_params.md b/generated/test/docs/clickhouse_params.md deleted file mode 100644 index c78f96d..0000000 --- a/generated/test/docs/clickhouse_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_clickhouse - -Service ID: `120` - -Service Name: ClickHouse - -[Manual](clickhouse.md) | [Create params](clickhouse_params_create.md) | [Modify params](clickhouse_params_modify.md) | [Output params](clickhouse_outputs.md) | [Operations](clickhouse_ops.md) | [Example](clickhouse_example.md) - -## Parameters - -- [Create params](clickhouse_params_create.md) -- [Modify params](clickhouse_params_modify.md) diff --git a/generated/test/docs/clickhouse_params_create.md b/generated/test/docs/clickhouse_params_create.md deleted file mode 100644 index 92fd988..0000000 --- a/generated/test/docs/clickhouse_params_create.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_clickhouse - -Service ID: `120` - -Service Name: ClickHouse - -[Manual](clickhouse.md) | [Create params](clickhouse_params_create.md) | [Modify params](clickhouse_params_modify.md) | [Output params](clickhouse_outputs.md) | [Operations](clickhouse_ops.md) | [Example](clickhouse_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
837startup_configurationmap-fixed
838cluster_configurationmap-fixed
839access_configurationmap-fixed
840clickhouse_keeper_configurationmap-fixed
841clickhouse_configurationmap-fixed
842backup_configurationmap-fixed
843autoscale_configurationmap-fixed
851clickhouse_files_configurationarray-map-fixedФормат:
- path: somethings3.xml
xmlConfig: '&lt;clickhouse&gt;......&lt;/clickhouse&gt;'
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/clickhouse_params_modify.md b/generated/test/docs/clickhouse_params_modify.md deleted file mode 100644 index d53484d..0000000 --- a/generated/test/docs/clickhouse_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_clickhouse - -Service ID: `120` - -Service Name: ClickHouse - -[Manual](clickhouse.md) | [Create params](clickhouse_params_create.md) | [Modify params](clickhouse_params_modify.md) | [Output params](clickhouse_outputs.md) | [Operations](clickhouse_ops.md) | [Example](clickhouse_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
844cluster_configurationmap-fixed
845clickhouse_keeper_configurationmap-fixed
846access_configurationmap-fixed
847clickhouse_configurationmap-fixed
848backup_configurationmap-fixed
849autoscale_configurationmap-fixed
850clickhouse_files_configurationarray-map-fixedФормат:
- path: somethings3.xml
xmlConfig: '&lt;clickhouse&gt;......&lt;/clickhouse&gt;'
diff --git a/generated/test/docs/clickhouse_user.md b/generated/test/docs/clickhouse_user.md deleted file mode 100644 index 60e4c96..0000000 --- a/generated/test/docs/clickhouse_user.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_clickhouse_user - -Service: `nubes_clickhouse` (ID: 120) - -[ClickHouse (основной)](clickhouse.md) | [Operations](clickhouse_ops.md) | [User](clickhouse_user.md) | [Example](clickhouse_user_example.md) - -## Create params - -**Обязательные параметры** - -None. - -**Параметры со значением по умолчанию** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
596usernamestringmyusernameПример: `myusername`regex=^(?![0-9_])[a-zA-Z_][a-zA-Z0-9_]{0,62}$; maxlength=62; minlength=2
598db_namearray-map-fixed[{}]
599access_hostsstring::/0Пример: `::/0`
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
601usernameИмя пользователя, созданное через операцию `create_user`
diff --git a/generated/test/docs/clickhouse_user_example.md b/generated/test/docs/clickhouse_user_example.md deleted file mode 100644 index 406e6d9..0000000 --- a/generated/test/docs/clickhouse_user_example.md +++ /dev/null @@ -1,35 +0,0 @@ -# Resource nubes_clickhouse_user — Example - -Service: `nubes_clickhouse` (ID: 120) - -[ClickHouse (основной)](clickhouse.md) | [Operations](clickhouse_ops.md) | [User](clickhouse_user.md) | [Example](clickhouse_user_example.md) - -## Copy-ready manifest (`clickhouse_user_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_clickhouse должен быть создан заранее -# resource "nubes_clickhouse" "baza" { ... } - -resource "nubes_clickhouse_user" "example" { - clickhouse_id = nubes_clickhouse.baza.id - - # Параметры со значением по умолчанию - username = "myusername" # Пример: `myusername` - db_name = [{}] - access_hosts = "::/0" # Пример: `::/0` -} -``` diff --git a/generated/test/docs/dnsrecord.md b/generated/test/docs/dnsrecord.md deleted file mode 100644 index 22f9734..0000000 --- a/generated/test/docs/dnsrecord.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## MAN - -
-Необходима DNS зона, в которой будет создана DNS запись.
Выберите
* Зону в которой будет создана запись
* Тип записи
* Имя записи
* Значение записи -
diff --git a/generated/test/docs/dnsrecord_example.md b/generated/test/docs/dnsrecord_example.md deleted file mode 100644 index 98f4f00..0000000 --- a/generated/test/docs/dnsrecord_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Copy-ready manifest (`dnsrecord_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_dnsrecord" "baza" { - zone_uid = "TODO" # UUID экземпляра услуги DNS-зоны - record_type = "A" # Тип DNS-записи - record_name = "TODO" # Имя записи. Имя зоны в конце проставляется автоматически - record_input = "TODO" # Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - record_ttl = 3600 # Time-to-Leave записи. Раз в какое время запись будет обновлена -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dnsrecord.baza.state_params["имя_ключа"] -nubes_dnsrecord.baza.state_out["имя_ключа"] -nubes_dnsrecord.baza.state_params_flat["имя_ключа"] -nubes_dnsrecord.baza.state_out_flat["имя_ключа"] -nubes_dnsrecord.baza.vault_secrets["имя_ключа"] -nubes_dnsrecord.baza.vault_url -nubes_dnsrecord.baza.vault_user_path -nubes_dnsrecord.baza.vault_fields -``` diff --git a/generated/test/docs/dnsrecord_ops.md b/generated/test/docs/dnsrecord_ops.md deleted file mode 100644 index 1ee6978..0000000 --- a/generated/test/docs/dnsrecord_ops.md +++ /dev/null @@ -1,14 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dnsrecord_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](dnsrecord_params_modify.md) -- `reconcile` diff --git a/generated/test/docs/dnsrecord_outputs.md b/generated/test/docs/dnsrecord_outputs.md deleted file mode 100644 index 4d127c2..0000000 --- a/generated/test/docs/dnsrecord_outputs.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dnsServers"]` -- `state_out_flat["record"]` - diff --git a/generated/test/docs/dnsrecord_params.md b/generated/test/docs/dnsrecord_params.md deleted file mode 100644 index 84701f9..0000000 --- a/generated/test/docs/dnsrecord_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Parameters - -- [Create params](dnsrecord_params_create.md) -- [Modify params](dnsrecord_params_modify.md) diff --git a/generated/test/docs/dnsrecord_params_create.md b/generated/test/docs/dnsrecord_params_create.md deleted file mode 100644 index a4a9ec3..0000000 --- a/generated/test/docs/dnsrecord_params_create.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
75zone_uiduuidUUID экземпляра услуги DNS-зоныref_svc_id=109
76record_typestringТип DNS-записиvalue_list=A, AAAA, CNAME, MX, PTR, SOA, SRV, TXT, LUA, NS, SSHFP
77record_namestringИмя записи. Имя зоны в конце проставляется автоматическиunique_scope=parent
78record_inputstringЗначение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
450record_ttlinteger3600Time-to-Leave записи. Раз в какое время запись будет обновленаminvalue=30; maxvalue=604800
diff --git a/generated/test/docs/dnsrecord_params_modify.md b/generated/test/docs/dnsrecord_params_modify.md deleted file mode 100644 index d3cdbdb..0000000 --- a/generated/test/docs/dnsrecord_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_dnsrecord - -Service ID: `111` - -Service Name: DNS запись - -[Manual](dnsrecord.md) | [Create params](dnsrecord_params_create.md) | [Modify params](dnsrecord_params_modify.md) | [Output params](dnsrecord_outputs.md) | [Operations](dnsrecord_ops.md) | [Example](dnsrecord_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
256record_inputstringЗапись. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP
diff --git a/generated/test/docs/dnszone.md b/generated/test/docs/dnszone.md deleted file mode 100644 index f8249dd..0000000 --- a/generated/test/docs/dnszone.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## MAN - -
-## ![image](https://img.icons8.com/?size=50&id=41400&format=png) Необходимо делегировать зону у регистратора на Авторитетные DNS (Сервера зон)

ns3.ngcloud.ru
``` bash
185.247.187.83
2a10:aa80:0:5::3
```

ns4.ngcloud.ru
``` bash
81.22.46.43
2a10:aa80:0:6::3
``` -
diff --git a/generated/test/docs/dnszone_example.md b/generated/test/docs/dnszone_example.md deleted file mode 100644 index 41e2355..0000000 --- a/generated/test/docs/dnszone_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Copy-ready manifest (`dnszone_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_dnszone" "baza" { - zone_email = "TODO" # Контактный e-mail - zone_name = "TODO" # Имя зоны - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - zone_kind = "NATIVE" # Тип зоны - zone_time_to_refresh = 86400 # Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов - zone_time_to_retry = 7200 # Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов - zone_time_to_expire = 3600000 # Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным - zone_time_to_live = 86400 # Время, в течение которого информация будет кешироваться другими DNS-серверами -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dnszone.baza.state_params["имя_ключа"] -nubes_dnszone.baza.state_out["имя_ключа"] -nubes_dnszone.baza.state_params_flat["имя_ключа"] -nubes_dnszone.baza.state_out_flat["имя_ключа"] -nubes_dnszone.baza.vault_secrets["имя_ключа"] -nubes_dnszone.baza.vault_url -nubes_dnszone.baza.vault_user_path -nubes_dnszone.baza.vault_fields -``` diff --git a/generated/test/docs/dnszone_ops.md b/generated/test/docs/dnszone_ops.md deleted file mode 100644 index e07344c..0000000 --- a/generated/test/docs/dnszone_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dnszone_params_create.md) -- `delete` diff --git a/generated/test/docs/dnszone_outputs.md b/generated/test/docs/dnszone_outputs.md deleted file mode 100644 index 0c3556d..0000000 --- a/generated/test/docs/dnszone_outputs.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dnsServers"]` -- `state_out_flat["dnsServers.ns1.nubes.ru"]` -- `state_out_flat["dnsServers.ns2.nubes.ru"]` -- `state_out_flat["zoneSerial"]` -- `state_out_flat["zoneSoaServer"]` - diff --git a/generated/test/docs/dnszone_params.md b/generated/test/docs/dnszone_params.md deleted file mode 100644 index 0f1f739..0000000 --- a/generated/test/docs/dnszone_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Parameters - -- [Create params](dnszone_params_create.md) -- [Modify params](dnszone_params_modify.md) diff --git a/generated/test/docs/dnszone_params_create.md b/generated/test/docs/dnszone_params_create.md deleted file mode 100644 index 0690a8f..0000000 --- a/generated/test/docs/dnszone_params_create.md +++ /dev/null @@ -1,31 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
66zone_emailstringКонтактный e-mail
67zone_namestringИмя зоныregex=^([a-z0-9-]+\.)+[a-z0-9-]+$
69zone_masters_for_slavestringИспользовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов
284resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
68zone_kindstringNATIVEТип зоныvalue_list=NATIVE, SLAVE
70zone_time_to_refreshstring86400Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов
71zone_time_to_retrystring7200Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов
72zone_time_to_expirestring3600000Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным
73zone_time_to_livestring86400Время, в течение которого информация будет кешироваться другими DNS-серверами
diff --git a/generated/test/docs/dnszone_params_modify.md b/generated/test/docs/dnszone_params_modify.md deleted file mode 100644 index bd1dc13..0000000 --- a/generated/test/docs/dnszone_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_dnszone - -Service ID: `110` - -Service Name: DNS зона - -[Manual](dnszone.md) | [Create params](dnszone_params_create.md) | [Modify params](dnszone_params_modify.md) | [Output params](dnszone_outputs.md) | [Operations](dnszone_ops.md) | [Example](dnszone_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/dummy.md b/generated/test/docs/dummy.md deleted file mode 100644 index 53f9855..0000000 --- a/generated/test/docs/dummy.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## MAN - -
-## Болванка для тестов.

А это просто много букв, чтобы посмотреть, как ведет себя текст при переполнении контейнера.


``` json
{
"iamServiceUrl": "https://auth-api-test.ngcloud.ru/api/v1/user",
"idpResponse": {
"prefix": {
"charset": "",
"status_text": "Request Time-out",
"text": true,
"errordetail": "",
"filecontent": "Connection Timeout",
"responseheader": {},
"header": "",
"statuscode": "408 Request Time-out",
"status_code": 408,
"mimetype": "Unable to determine MIME type of file."
}
}
}
``` -
diff --git a/generated/test/docs/dummy_example.md b/generated/test/docs/dummy_example.md deleted file mode 100644 index f384517..0000000 --- a/generated/test/docs/dummy_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Copy-ready manifest (`dummy_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_dummy" "baza" { - resource_realm = "TODO" # Платформа для развертывания - arr = "test" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - duration_ms = 0 # перед завершением подождать (sleep) столько миллисекунд - fail_at_start = false # если true, завершить джоб, ничего не записывая в cmdb - fail_in_progress = false # если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - where_fail = 1 # принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_dummy.baza.state_params["имя_ключа"] -nubes_dummy.baza.state_out["имя_ключа"] -nubes_dummy.baza.state_params_flat["имя_ключа"] -nubes_dummy.baza.state_out_flat["имя_ключа"] -nubes_dummy.baza.vault_secrets["имя_ключа"] -nubes_dummy.baza.vault_url -nubes_dummy.baza.vault_user_path -nubes_dummy.baza.vault_fields -``` diff --git a/generated/test/docs/dummy_ops.md b/generated/test/docs/dummy_ops.md deleted file mode 100644 index 3af1a55..0000000 --- a/generated/test/docs/dummy_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](dummy_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](dummy_params_modify.md) -- `reconcile` -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/test/docs/dummy_outputs.md b/generated/test/docs/dummy_outputs.md deleted file mode 100644 index 52b99e1..0000000 --- a/generated/test/docs/dummy_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `vault_secrets` ключи - -- `vault_secrets["someKey"]` - diff --git a/generated/test/docs/dummy_params.md b/generated/test/docs/dummy_params.md deleted file mode 100644 index 67ae088..0000000 --- a/generated/test/docs/dummy_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Parameters - -- [Create params](dummy_params_create.md) -- [Modify params](dummy_params_modify.md) diff --git a/generated/test/docs/dummy_params_create.md b/generated/test/docs/dummy_params_create.md deleted file mode 100644 index 69e3367..0000000 --- a/generated/test/docs/dummy_params_create.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
242resource_realmstringНаименование ресурсной платформы для подключенияfunc=getAvailableResourceRealms
286bodymessagestringДата, уходящая в Vault
321map_examplemap
322json_examplejsonДля тестирования интерфейса. Сюда можно писать корректный json
396nested_ref_example
647map_fixedmap-fixedНовый тип поля
654array_map_fixed_examplearray-map-fixedArray of map-fixed
863arrarrayvalue_list=test, 2, val1
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
198duration_msinteger0перед завершением подождать (sleep) столько миллисекунд
199fail_at_startbooleanfalse**Операция не будет завершена**
Она будет в постоянном статусе PENDING, однако в Jenkins Job завершится с ошибкой
value_list=false, true
200fail_in_progressbooleanfalseесли true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdbvalue_list=false, true
201where_failinteger1принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault writevalue_list=1, 2, 3
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/dummy_params_modify.md b/generated/test/docs/dummy_params_modify.md deleted file mode 100644 index b601221..0000000 --- a/generated/test/docs/dummy_params_modify.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_dummy - -Service ID: `1` - -Service Name: Болванка - -[Manual](dummy.md) | [Create params](dummy_params_create.md) | [Modify params](dummy_params_modify.md) | [Output params](dummy_outputs.md) | [Operations](dummy_ops.md) | [Example](dummy_example.md) - -## Modify params - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
287duration_msintegerперед завершением подождать (sleep) столько миллисекунд
288fail_at_startbooleanесли true, завершить джоб, ничего не записывая в cmdbvalue_list=false, true
289fail_in_progressbooleanесли true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdbvalue_list=false, true
290where_failintegerпринимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault writevalue_list=1, 2, 3
291bodymessageДата, уходящая в Vault
373map_examplemap
374json_example
diff --git a/generated/test/docs/flask.md b/generated/test/docs/flask.md deleted file mode 100644 index 763135a..0000000 --- a/generated/test/docs/flask.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## MAN - -
-# Инструкция по развертыванию Web-сервер с фреймворком Flask через платформу

## 1. Общая информация

Сервис **Web-сервер с фреймворком Flask** предназначен для развертывания веб-приложений на базе Flask.

### Доступные операции

create — включить сервис, развернуть веб-приложение с указанными параметрами.
delete — удалить сервис, только после suspend.
modify — изменить настройки сервиса и переразвернуть.
suspend — выключить веб-приложение, остановить обслуживание.
resume — включить веб-приложение после suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Имя домена
Описание: доменное имя для доступа к веб-приложению. Если указан FQDN, происходит проверка DNS на валидность А-записи. А-запись должна указывать на балансировщик ресурсной платформы. Если указано имя в рамках одного октета, оно будет добавлено в публичную DNS-зону.
Пример значения: строка, допустимые FQDN или имя в одном октете. Пример: example.com или myapp.

### Платформа для развертывания
Описание: кластер Kubernetes, в котором будет развернуто приложение.
Пример значения: идентификатор кластера Kubernetes.

### Квота ядра пода
Описание: количество CPU, выделяемое на под, в Milicores.
Пример значения: целое число, например 500 для 0.5 ядра.

### Квота памяти пода
Описание: количество памяти, выделяемое на под, в Megabytes.
Пример значения: целое число, например 512 для 512 MB.

### Кол-во реплик пода
Описание: количество инстансов пода для масштабирования.
Пример значения: целое число, шт, например 2.

### URL Проекта (gitpath)
Описание: полный HTTPS путь до проекта в Git-репозитории.
Пример значения: URL в формате https://github.com/myuser/myproject.git. Доступ к репозиторию должен быть публичным.

### URL HealthCheck
Описание: путь для проверки здоровья приложения внутри пода.
Пример значения: строка, путь, например /api/v1/health.

### Переменные окружения пода
Описание: структура данных, которая будет передана как переменные окружения в под.
Пример значения: ключ-значение, например {"ENV": "production"}.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Квота ядра пода: 300m (0.3 ядра)
- Квота памяти пода: 256 MB
- Кол-во реплик пода: 1

### Промышленное окружение
- Квота ядра пода: от 1000m (1 ядро) в зависимости от нагрузки
- Квота памяти пода: от 1024 MB (1 GB) с учетом потребностей приложения
- Кол-во реплик пода: от 2 для обеспечения отказоустойчивости

---

## 4. Выходные параметры
Операция create не возвращает явных выходных параметров. Успешное выполнение операции приводит к развертыванию сервиса, доступного по указанному домену.

---

## 5. Дополнительная информация
- В корне проекта должен находиться файл requirements.txt со списком зависимостей Python.
- Исходный код веб-приложения должен располагаться в директории site.
- Запуск веб-сервера осуществляется командой python app.py.
- Используется версия Python: python:3.12-slim.
- Git-репозиторий должен быть публично доступен для платформы.
- Операция delete возможна только после suspend.
- Операция modify приводит к переразвертыванию с новыми параметрами. -
diff --git a/generated/test/docs/flask_example.md b/generated/test/docs/flask_example.md deleted file mode 100644 index 5d15690..0000000 --- a/generated/test/docs/flask_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Copy-ready manifest (`flask_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_flask" "baza" { - startup_configuration = "TODO" - cluster_configuration = "TODO" - access_configuration = "TODO" - app_configuration = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - json_env = {} -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_flask.baza.state_params["имя_ключа"] -nubes_flask.baza.state_out["имя_ключа"] -nubes_flask.baza.state_params_flat["имя_ключа"] -nubes_flask.baza.state_out_flat["имя_ключа"] -nubes_flask.baza.vault_secrets["имя_ключа"] -nubes_flask.baza.vault_url -nubes_flask.baza.vault_user_path -nubes_flask.baza.vault_fields -``` diff --git a/generated/test/docs/flask_ops.md b/generated/test/docs/flask_ops.md deleted file mode 100644 index a9ff50c..0000000 --- a/generated/test/docs/flask_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](flask_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](flask_params_modify.md) -- `reconcile` -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/test/docs/flask_outputs.md b/generated/test/docs/flask_outputs.md deleted file mode 100644 index 3c2d51a..0000000 --- a/generated/test/docs/flask_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/flask_params.md b/generated/test/docs/flask_params.md deleted file mode 100644 index ca3f639..0000000 --- a/generated/test/docs/flask_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Parameters - -- [Create params](flask_params_create.md) -- [Modify params](flask_params_modify.md) diff --git a/generated/test/docs/flask_params_create.md b/generated/test/docs/flask_params_create.md deleted file mode 100644 index cb3cdfb..0000000 --- a/generated/test/docs/flask_params_create.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
1037startup_configurationmap-fixed
1038cluster_configurationmap-fixed
1039access_configurationmap-fixed
1040app_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
1041json_envmap{}
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/flask_params_modify.md b/generated/test/docs/flask_params_modify.md deleted file mode 100644 index 9043feb..0000000 --- a/generated/test/docs/flask_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_flask - -Service ID: `89` - -Service Name: Web-сервер с фреймворком Flask - -[Manual](flask.md) | [Create params](flask_params_create.md) | [Modify params](flask_params_modify.md) | [Output params](flask_outputs.md) | [Operations](flask_ops.md) | [Example](flask_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
1042cluster_configurationmap-fixed
1043app_configurationmap-fixed
1044json_envmap
diff --git a/generated/test/docs/gitea.md b/generated/test/docs/gitea.md deleted file mode 100644 index 8b02101..0000000 --- a/generated/test/docs/gitea.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## MAN - -
-# Инструкция по развертыванию Gitea через платформу

---
## 1. Общая информация
Gitea — это лёгкий, быстрый и самодостаточный сервис хостинга Git-репозиториев с веб-интерфейсом.
Позволяет создавать и управлять репозиториями, организациями, командами, а также настраивать CI/CD через интеграции.
Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание сервиса Gitea
- **delete** — Удаление сервиса Gitea
- **modify** — Модификация сервиса Gitea
- **suspend** — Остановка сервиса Gitea
- **resume** — Запуск сервиса Gitea

---
## 2. Параметры развертывания
Ниже перечислены параметры, которые необходимо указать при создании ресурса Gitea:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развёрнут сервис). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество реплик подов Gitea. Пример: `1`

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `1024`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `500`

* **Размер (gigabyte) диска для базы данных:**
Размер PVC для хранения репозиториев и данных Gitea в гигабайтах. Пример: `10`

* **FQDN / Домен:**
Доменное имя, по которому будет доступен сервис. Пример: `git.example.com`

* **Инстанс услуги PostgreSQL:**
UUID услуги k8sPgsql, в которой будет создана база данных `gitea` и пользователь `techgitea`.

* **Дополнительные параметры сервера (iniServerParams):**
JSON-объект с дополнительными параметрами секции `[server]` в `app.ini`. Пример:
```json
{"MAX_CONTENT_LENGTH": "524288000"}
```

* **Дополнительные annotations для Ingress (ingressExtraAnnotations):**
JSON-объект с дополнительными annotations для Ingress-контроллера. Пример:
```json
{"nginx.ingress.kubernetes.io/proxy-body-size": "500m"}
```

---
## 3. Особенности подключения и работы с репозиториями

### 3.1. Доступ только по HTTPS
Сервис развёртывается с **rootless-образом** Gitea. SSH-сервер внутри и он **доступен только внутри кластера Kubernetes**.

**Внешний доступ к репозиториям осуществляется исключительно по HTTPS через Ingress.**

```bash
# Пример клонирования
https://<домен>/<пользователь>/<репозиторий>.git
```

### 3.2. Настройка git для передачи логина и пароля
Для работы с приватными репозиториями через HTTPS необходимо передать учётные данные. Рекомендуется использовать один из следующих способов:

**Встроить креды в URL remote**
```bash
git remote set-url origin https://<логин>:<пароль>@<домен>/<пользователь>/<репозиторий>.git
```
> **Важно:** Логин и пароль администратора создаются автоматически при развертывании и хранятся в Vault.

### 3.3. Работа с большими файлами
По умолчанию `MAX_CONTENT_LENGTH` установлен в **500 МБ**, а Ingress пропускает pack-файлы до **500 МБ**.

Если необходимо запушить файлы близкие к лимиту, увеличьте HTTP-буфер git на стороне клиента:
```bash
git config http.postBuffer 524288000
```

Для файлов **более 500 МБ** рекомендуется использовать **Git LFS**.

---
## 4. Выходные параметры
После успешного развертывания ресурса Gitea платформа возвращает ряд параметров.

Ключевым из них является:

**connectionUrl**
Это внешний URL для доступа к веб-интерфейсу и Git-репозиториям по HTTPS. Пример:
```
https://git.example.com
```

**internalConnect**
Внутренний эндпоинт для подключения к PostgreSQL из других сервисов внутри кластера.

---
## 5. Дополнительная информация
- База данных `gitea` и пользователь `techgitea` создаются автоматически в указанной услуге PostgreSQL.
- DNS-запись и TLS-сертификат (Let's Encrypt) настраиваются автоматически на основе указанного домена.
- Для изменения параметров сервера Gitea (`app.ini`) используйте операцию **modify** с полем `iniServerParams`.
- Для добавления дополнительных Ingress-annotations используйте операцию **modify** с полем `ingressExtraAnnotations`.
--- -
diff --git a/generated/test/docs/gitea_complex.md b/generated/test/docs/gitea_complex.md deleted file mode 100644 index b67da5e..0000000 --- a/generated/test/docs/gitea_complex.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## MAN - -
-Комплексная услуга из ["gittea", "postgres"] -
diff --git a/generated/test/docs/gitea_complex_example.md b/generated/test/docs/gitea_complex_example.md deleted file mode 100644 index 2689001..0000000 --- a/generated/test/docs/gitea_complex_example.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Copy-ready manifest (`gitea_complex_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_gitea_complex" "baza" { -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_gitea_complex.baza.state_params["имя_ключа"] -nubes_gitea_complex.baza.state_out["имя_ключа"] -nubes_gitea_complex.baza.state_params_flat["имя_ключа"] -nubes_gitea_complex.baza.state_out_flat["имя_ключа"] -nubes_gitea_complex.baza.vault_secrets["имя_ключа"] -nubes_gitea_complex.baza.vault_url -nubes_gitea_complex.baza.vault_user_path -nubes_gitea_complex.baza.vault_fields -``` diff --git a/generated/test/docs/gitea_complex_ops.md b/generated/test/docs/gitea_complex_ops.md deleted file mode 100644 index 4612ff3..0000000 --- a/generated/test/docs/gitea_complex_ops.md +++ /dev/null @@ -1,10 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Operations - diff --git a/generated/test/docs/gitea_complex_outputs.md b/generated/test/docs/gitea_complex_outputs.md deleted file mode 100644 index f0593c8..0000000 --- a/generated/test/docs/gitea_complex_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/gitea_complex_params.md b/generated/test/docs/gitea_complex_params.md deleted file mode 100644 index ad58e7f..0000000 --- a/generated/test/docs/gitea_complex_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Parameters - -- [Create params](gitea_complex_params_create.md) -- [Modify params](gitea_complex_params_modify.md) diff --git a/generated/test/docs/gitea_complex_params_create.md b/generated/test/docs/gitea_complex_params_create.md deleted file mode 100644 index 2f57dfd..0000000 --- a/generated/test/docs/gitea_complex_params_create.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - -None. - -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/test/docs/gitea_complex_params_modify.md b/generated/test/docs/gitea_complex_params_modify.md deleted file mode 100644 index 472dee0..0000000 --- a/generated/test/docs/gitea_complex_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_gitea_complex - -Service ID: `114` - -Service Name: Комплексная услуга по созданию gitea - -[Manual](gitea_complex.md) | [Create params](gitea_complex_params_create.md) | [Modify params](gitea_complex_params_modify.md) | [Output params](gitea_complex_outputs.md) | [Operations](gitea_complex_ops.md) | [Example](gitea_complex_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/gitea_example.md b/generated/test/docs/gitea_example.md deleted file mode 100644 index 9573be7..0000000 --- a/generated/test/docs/gitea_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Copy-ready manifest (`gitea_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_gitea" "baza" { - psql_uid = "TODO" # UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_gitea.baza.state_params["имя_ключа"] -nubes_gitea.baza.state_out["имя_ключа"] -nubes_gitea.baza.state_params_flat["имя_ключа"] -nubes_gitea.baza.state_out_flat["имя_ключа"] -nubes_gitea.baza.vault_secrets["имя_ключа"] -nubes_gitea.baza.vault_url -nubes_gitea.baza.vault_user_path -nubes_gitea.baza.vault_fields -``` diff --git a/generated/test/docs/gitea_ops.md b/generated/test/docs/gitea_ops.md deleted file mode 100644 index 0b22aac..0000000 --- a/generated/test/docs/gitea_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](gitea_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](gitea_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/test/docs/gitea_outputs.md b/generated/test/docs/gitea_outputs.md deleted file mode 100644 index 3944814..0000000 --- a/generated/test/docs/gitea_outputs.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` - diff --git a/generated/test/docs/gitea_params.md b/generated/test/docs/gitea_params.md deleted file mode 100644 index f0931ff..0000000 --- a/generated/test/docs/gitea_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Parameters - -- [Create params](gitea_params_create.md) -- [Modify params](gitea_params_modify.md) diff --git a/generated/test/docs/gitea_params_create.md b/generated/test/docs/gitea_params_create.md deleted file mode 100644 index 4f75b95..0000000 --- a/generated/test/docs/gitea_params_create.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
238psql_uiduuidUUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматическиref_svc_id=90
818ingress_extra_annotationsmap
821ini_server_paramsmap
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
232resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=300; maxvalue=4000
233resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=256; maxvalue=8192
234resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
235resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
237domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/gitea_params_modify.md b/generated/test/docs/gitea_params_modify.md deleted file mode 100644 index d86886b..0000000 --- a/generated/test/docs/gitea_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_gitea - -Service ID: `99` - -Service Name: Gitea - -[Manual](gitea.md) | [Create params](gitea_params_create.md) | [Modify params](gitea_params_modify.md) | [Output params](gitea_outputs.md) | [Operations](gitea_ops.md) | [Example](gitea_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
259resource_cpuintegerКвота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=500; maxvalue=4000
260resource_memoryintegerКвота памяти пода (Указывается в Megabytes)minvalue=256; maxvalue=8192
261resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
262resource_instancesintegerКоличество узлов в сетиminvalue=1; maxvalue=7
819ingress_extra_annotationsmapПримеры:
- `nginx.ingress.kubernetes.io/proxy-body-size: 500m` (Размер пакета)
- `nginx.ingress.kubernetes.io/proxy-read-timeout: &quot;600&quot;` (Время ожидания при чтении)
- `nginx.ingress.kubernetes.io/proxy-send-timeout: &quot;600&quot;` (Время ожидания отправке)
820ini_server_paramsmapПримеры:
- `MAX_CONTENT_LENGTH: 524288000(~500мб)` (Размер пакета в байтах)
diff --git a/generated/test/docs/harbor.md b/generated/test/docs/harbor.md deleted file mode 100644 index c0cad0a..0000000 --- a/generated/test/docs/harbor.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## MAN - -
-Расширенный реестр для управления Docker-образами с enterprise-функциями безопасности, репликации и контроля доступа.
Container Registry позволяет хранить, развертывать и управлять Docker-образами контейнеров в инфраструктуре NGcloud.
Сервис можно использовать в процессе разработки контейнеров. Например, вы можете настроить систему автоматизации на работу с реестром в Container Registry в рамках процесса непрерывной интеграции. Контейнеры идеально подходят для запуска небольших, независимых и легко изменяемых сервисов.
Чтобы начать работу, создайте реестр и загрузите в него Docker-образ
Авторизация: keycloak -
diff --git a/generated/test/docs/harbor_example.md b/generated/test/docs/harbor_example.md deleted file mode 100644 index 57e7708..0000000 --- a/generated/test/docs/harbor_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Copy-ready manifest (`harbor_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_harbor" "baza" { - resource_realm = "TODO" # Платформа для развертывания - s3_uid = "TODO" # UUID экземпляра услуги S3 - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 100 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 200 # Квота памяти пода (Указывается в Megabytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_harbor.baza.state_params["имя_ключа"] -nubes_harbor.baza.state_out["имя_ключа"] -nubes_harbor.baza.state_params_flat["имя_ключа"] -nubes_harbor.baza.state_out_flat["имя_ключа"] -nubes_harbor.baza.vault_secrets["имя_ключа"] -nubes_harbor.baza.vault_url -nubes_harbor.baza.vault_user_path -nubes_harbor.baza.vault_fields -``` diff --git a/generated/test/docs/harbor_ops.md b/generated/test/docs/harbor_ops.md deleted file mode 100644 index c97c401..0000000 --- a/generated/test/docs/harbor_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](harbor_params_create.md) -- `delete` — DEV-Ветка удаления Harbor -- `modify` — Изменение кластера. Параметры: [Modify params](harbor_params_modify.md) diff --git a/generated/test/docs/harbor_outputs.md b/generated/test/docs/harbor_outputs.md deleted file mode 100644 index 3422bbd..0000000 --- a/generated/test/docs/harbor_outputs.md +++ /dev/null @@ -1,40 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.k8sregistry"]` -- `state_out_flat["monitoring.k8sregistry.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` - diff --git a/generated/test/docs/harbor_params.md b/generated/test/docs/harbor_params.md deleted file mode 100644 index 6819254..0000000 --- a/generated/test/docs/harbor_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Parameters - -- [Create params](harbor_params_create.md) -- [Modify params](harbor_params_modify.md) diff --git a/generated/test/docs/harbor_params_create.md b/generated/test/docs/harbor_params_create.md deleted file mode 100644 index f51594a..0000000 --- a/generated/test/docs/harbor_params_create.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
110resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
231s3_uiduuidUUID экземпляра услуги S3ref_svc_id=12
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
16domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
228resource_cpuinteger100Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=500; maxvalue=4000
229resource_memoryinteger200Квота памяти пода (Указывается в Megabytes)minvalue=512; maxvalue=8192
230resource_instancesinteger1Количество узлов в сетиminvalue=1; maxvalue=7
diff --git a/generated/test/docs/harbor_params_modify.md b/generated/test/docs/harbor_params_modify.md deleted file mode 100644 index 71d42a0..0000000 --- a/generated/test/docs/harbor_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_harbor - -Service ID: `82` - -Service Name: Container Registry - -[Manual](harbor.md) | [Create params](harbor_params_create.md) | [Modify params](harbor_params_modify.md) | [Output params](harbor_outputs.md) | [Operations](harbor_ops.md) | [Example](harbor_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
822resource_instancesintegerminvalue=1; maxvalue=7
823resource_cpuintegerminvalue=500; maxvalue=4000
824resource_memoryintegerminvalue=512; maxvalue=8192
diff --git a/generated/test/docs/http.md b/generated/test/docs/http.md deleted file mode 100644 index 68075b0..0000000 --- a/generated/test/docs/http.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/http_example.md b/generated/test/docs/http_example.md deleted file mode 100644 index ce0a042..0000000 --- a/generated/test/docs/http_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Copy-ready manifest (`http_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_http" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 100 # Квота ядра пода (Указывается в mili) - resource_memory = 200 # Квота памяти пода (Указывается в Megabytes) - resource_instances = 1 # Количество узлов - registry_path = "nexus-sa.tst.nubes.ru/docker-nubes/jolt" # Путь до image, который будет установлен как deployment - ingress_annotations = {} # Формат ключ/значение Поддерживает пока простые аннотации -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_http.baza.state_params["имя_ключа"] -nubes_http.baza.state_out["имя_ключа"] -nubes_http.baza.state_params_flat["имя_ключа"] -nubes_http.baza.state_out_flat["имя_ключа"] -nubes_http.baza.vault_secrets["имя_ключа"] -nubes_http.baza.vault_url -nubes_http.baza.vault_user_path -nubes_http.baza.vault_fields -``` diff --git a/generated/test/docs/http_ops.md b/generated/test/docs/http_ops.md deleted file mode 100644 index fb7982b..0000000 --- a/generated/test/docs/http_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](http_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](http_params_modify.md) -- `reconcile` -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/test/docs/http_outputs.md b/generated/test/docs/http_outputs.md deleted file mode 100644 index 9baf737..0000000 --- a/generated/test/docs/http_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/test/docs/http_params.md b/generated/test/docs/http_params.md deleted file mode 100644 index 07aa372..0000000 --- a/generated/test/docs/http_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Parameters - -- [Create params](http_params_create.md) -- [Modify params](http_params_modify.md) diff --git a/generated/test/docs/http_params_create.md b/generated/test/docs/http_params_create.md deleted file mode 100644 index 2add22b..0000000 --- a/generated/test/docs/http_params_create.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
216resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
241json_envmapМассив переменных, будут переданы в env приложения
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
212domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
213resource_cpuinteger100Квота ядра пода (Указывается в mili)minvalue=100; maxvalue=4000
214resource_memoryinteger200Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
215resource_instancesinteger1Количество реплик приложения. Трафик будет распределяться между подами в режиме Round-Robinminvalue=1; maxvalue=7
217registry_pathstringnexus-sa.tst.nubes.ru/docker-nubes/joltПуть до image, который будет установлен как deployment
782ingress_annotationsmap{}Формат ключ/значение
Поддерживает пока простые аннотации
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/http_params_modify.md b/generated/test/docs/http_params_modify.md deleted file mode 100644 index 75a69ec..0000000 --- a/generated/test/docs/http_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_http - -Service ID: `98` - -Service Name: Простой HTTP контейнер - -[Manual](http.md) | [Create params](http_params_create.md) | [Modify params](http_params_modify.md) | [Output params](http_outputs.md) | [Operations](http_ops.md) | [Example](http_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
218resource_cpuintegerminvalue=100; maxvalue=4000
219resource_memoryintegerminvalue=128; maxvalue=8192
220resource_instancesintegerКоличество узловminvalue=1; maxvalue=7
diff --git a/generated/test/docs/index.md b/generated/test/docs/index.md deleted file mode 100644 index 28a360a..0000000 --- a/generated/test/docs/index.md +++ /dev/null @@ -1,47 +0,0 @@ -# Ресурсы провайдера - -| ID | Ресурс | Описание | -|-----|--------|----------| -| 1 | [nubes_dummy](dummy.md) | Болванка | -| 2 | [nubes_template](template.md) | Темплейт k8s | -| 12 | [nubes_s3](s3.md) | S3 Object Storage | -| 13 | [nubes_s3bucket](s3bucket.md) | S3 бакет | -| 19 | [nubes_vc_org](vc_org.md) | Организация в Cloud Director | -| 20 | [nubes_vc_org_saas](vc_org_saas.md) | Организация [DEPRECATED] | -| 21 | [nubes_vc_vdc](vc_vdc.md) | Виртуальный датацентр (vDC) | -| 22 | [nubes_vc_nsxt](vc_nsxt.md) | Сетевой шлюз периметра (Edge) | -| 23 | [nubes_vc_vm](vc_vm.md) | VM в Cloud Director (старый формат) (vc_vm) | -| 25 | [nubes_vcexternalip](vcexternalip.md) | Публичные IP адреса | -| 26 | [nubes_vapp](vapp.md) | Виртуальный каталог ВМ (vApp) | -| 27 | [nubes_vc_vm_v2](vc_vm_v2.md) | VM в Cloud Director (vc_vmV2) | -| 28 | [nubes_vc_vm_v3](vc_vm_v3.md) | Виртуальная машина | -| 29 | [nubes_vc_vdc_group](vc_vdc_group.md) | Группа датацентров | -| 32 | [nubes_vmpostgre](vmpostgre.md) | vc_vm_postgresql_std | -| 50 | [nubes_nextcloud](nextcloud.md) | Nextcloud | -| 81 | [nubes_superset](superset.md) | Apache Superset | -| 82 | [nubes_harbor](harbor.md) | Container Registry | -| 88 | [nubes_k8s_ziti_controller](k8s_ziti_controller.md) | k8sZitiController | -| 89 | [nubes_flask](flask.md) | Web-сервер с фреймворком Flask | -| 90 | [nubes_postgres](postgres.md) | PostgreSQL | -| 91 | [nubes_redis](redis.md) | Redis | -| 92 | [nubes_mongodb](mongodb.md) | MongoDB | -| 93 | [nubes_rabbitmq](rabbitmq.md) | RabbitMQ | -| 94 | [nubes_lucee](lucee.md) | Lucee | -| 95 | [nubes_nodejs](nodejs.md) | NodeJS | -| 96 | [nubes_pgadmin](pgadmin.md) | pgAdmin | -| 97 | [nubes_nodered](nodered.md) | NodeRed | -| 98 | [nubes_http](http.md) | Простой HTTP контейнер | -| 99 | [nubes_gitea](gitea.md) | Gitea | -| 100 | [nubes_openwhisk](openwhisk.md) | Serverless Openwhisk (openwhisk_tenant) | -| 110 | [nubes_dnszone](dnszone.md) | DNS зона | -| 111 | [nubes_dnsrecord](dnsrecord.md) | DNS запись | -| 112 | [nubes_tenant](tenant.md) | Тенант в Grafana | -| 113 | [nubes_vc_complex](vc_complex.md) | Быстрый старт | -| 114 | [nubes_gitea_complex](gitea_complex.md) | Комплексная услуга по созданию gitea | -| 115 | [nubes_mariadb](mariadb.md) | Mariadb | -| 116 | [nubes_kafka](kafka.md) | ApacheKafka | -| 117 | [nubes_nifi](nifi.md) | Nifi | -| 119 | [nubes_akhq](akhq.md) | Akhq | -| 120 | [nubes_clickhouse](clickhouse.md) | ClickHouse | -| 149 | [nubes_valo_tenant](valo_tenant.md) | VALO Cloud | -| 150 | [nubes_k8s_sthutrval_cluster](k8s_sthutrval_cluster.md) | Kubernetes кластер Штурвал | diff --git a/generated/test/docs/k8s_sthutrval_cluster.md b/generated/test/docs/k8s_sthutrval_cluster.md deleted file mode 100644 index b3b0523..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## MAN - -
-Перед разворачиванием убедиться, что в облаке есть 2 свободных невыделенных IP в пуле -
diff --git a/generated/test/docs/k8s_sthutrval_cluster_example.md b/generated/test/docs/k8s_sthutrval_cluster_example.md deleted file mode 100644 index 8c8b5b2..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Copy-ready manifest (`k8s_sthutrval_cluster_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_k8s_sthutrval_cluster" "baza" { - startup_configuration = "TODO" - control_plane_configuration = "TODO" - access_configuration = "TODO" - cluster_configuration = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - worker_configuration = [{}] -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_k8s_sthutrval_cluster.baza.state_params["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_out["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_params_flat["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.state_out_flat["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.vault_secrets["имя_ключа"] -nubes_k8s_sthutrval_cluster.baza.vault_url -nubes_k8s_sthutrval_cluster.baza.vault_user_path -nubes_k8s_sthutrval_cluster.baza.vault_fields -``` diff --git a/generated/test/docs/k8s_sthutrval_cluster_ops.md b/generated/test/docs/k8s_sthutrval_cluster_ops.md deleted file mode 100644 index e15a212..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster_ops.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](k8s_sthutrval_cluster_params_create.md) -- `create_user` — . См. [nubes_k8s_sthutrval_cluster_user](k8s_sthutrval_cluster_user.md) -- `delete` -- `delete_user` — . См. [nubes_k8s_sthutrval_cluster_user](k8s_sthutrval_cluster_user.md) -- `modify` — Изменение кластера. Параметры: [Modify params](k8s_sthutrval_cluster_params_modify.md) -- `reconcile` -- `resume` -- `suspend` diff --git a/generated/test/docs/k8s_sthutrval_cluster_outputs.md b/generated/test/docs/k8s_sthutrval_cluster_outputs.md deleted file mode 100644 index 065be3b..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster_outputs.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["ingressAddress"]` -- `state_out_flat["kubernetesApiAddress"]` - -### `vault_secrets` ключи - -- `vault_secrets["kubernetesAdminConfigB64"]` - diff --git a/generated/test/docs/k8s_sthutrval_cluster_params.md b/generated/test/docs/k8s_sthutrval_cluster_params.md deleted file mode 100644 index 641f838..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Parameters - -- [Create params](k8s_sthutrval_cluster_params_create.md) -- [Modify params](k8s_sthutrval_cluster_params_modify.md) diff --git a/generated/test/docs/k8s_sthutrval_cluster_params_create.md b/generated/test/docs/k8s_sthutrval_cluster_params_create.md deleted file mode 100644 index 4ecc132..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster_params_create.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
750startup_configurationmap-fixed
751control_plane_configurationmap-fixed
753access_configurationmap-fixed
755cluster_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
752worker_configurationarray-map-fixed[{}]
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/k8s_sthutrval_cluster_params_modify.md b/generated/test/docs/k8s_sthutrval_cluster_params_modify.md deleted file mode 100644 index f2f26fb..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster - -Service ID: `150` - -Service Name: Kubernetes кластер Штурвал - -[Manual](k8s_sthutrval_cluster.md) | [Create params](k8s_sthutrval_cluster_params_create.md) | [Modify params](k8s_sthutrval_cluster_params_modify.md) | [Output params](k8s_sthutrval_cluster_outputs.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [Example](k8s_sthutrval_cluster_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
756cluster_configurationmap-fixed
757control_plane_configurationmap-fixed
758worker_configurationarray-map-fixed
759access_configurationmap-fixed
diff --git a/generated/test/docs/k8s_sthutrval_cluster_user.md b/generated/test/docs/k8s_sthutrval_cluster_user.md deleted file mode 100644 index df2fe99..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster_user.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster_user - -Service: `nubes_k8s_sthutrval_cluster` (ID: 150) - -[Kubernetes кластер Штурвал (основной)](k8s_sthutrval_cluster.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [User](k8s_sthutrval_cluster_user.md) | [Example](k8s_sthutrval_cluster_user_example.md) - -## Create params - -**Обязательные параметры** - -None. - -**Параметры со значением по умолчанию** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
869adminsarray-map-fixed[{}]
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
870adminsarray-map-fixed
diff --git a/generated/test/docs/k8s_sthutrval_cluster_user_example.md b/generated/test/docs/k8s_sthutrval_cluster_user_example.md deleted file mode 100644 index cca35a5..0000000 --- a/generated/test/docs/k8s_sthutrval_cluster_user_example.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_k8s_sthutrval_cluster_user — Example - -Service: `nubes_k8s_sthutrval_cluster` (ID: 150) - -[Kubernetes кластер Штурвал (основной)](k8s_sthutrval_cluster.md) | [Operations](k8s_sthutrval_cluster_ops.md) | [User](k8s_sthutrval_cluster_user.md) | [Example](k8s_sthutrval_cluster_user_example.md) - -## Copy-ready manifest (`k8s_sthutrval_cluster_user_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_k8s_sthutrval_cluster должен быть создан заранее -# resource "nubes_k8s_sthutrval_cluster" "baza" { ... } - -resource "nubes_k8s_sthutrval_cluster_user" "example" { - k8s_sthutrval_cluster_id = nubes_k8s_sthutrval_cluster.baza.id - - # Параметры со значением по умолчанию - admins = [{}] -} -``` diff --git a/generated/test/docs/k8s_ziti_controller.md b/generated/test/docs/k8s_ziti_controller.md deleted file mode 100644 index 5c8b8f3..0000000 --- a/generated/test/docs/k8s_ziti_controller.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/k8s_ziti_controller_example.md b/generated/test/docs/k8s_ziti_controller_example.md deleted file mode 100644 index e5df3c7..0000000 --- a/generated/test/docs/k8s_ziti_controller_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Copy-ready manifest (`k8s_ziti_controller_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_k8s_ziti_controller" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 300 # Квота ядра пода (milicores) - resource_memory = 512 # Квота памяти пода (MBytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_k8s_ziti_controller.baza.state_params["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_out["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_params_flat["имя_ключа"] -nubes_k8s_ziti_controller.baza.state_out_flat["имя_ключа"] -nubes_k8s_ziti_controller.baza.vault_secrets["имя_ключа"] -nubes_k8s_ziti_controller.baza.vault_url -nubes_k8s_ziti_controller.baza.vault_user_path -nubes_k8s_ziti_controller.baza.vault_fields -``` diff --git a/generated/test/docs/k8s_ziti_controller_ops.md b/generated/test/docs/k8s_ziti_controller_ops.md deleted file mode 100644 index 8da7234..0000000 --- a/generated/test/docs/k8s_ziti_controller_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](k8s_ziti_controller_params_create.md) -- `delete` diff --git a/generated/test/docs/k8s_ziti_controller_outputs.md b/generated/test/docs/k8s_ziti_controller_outputs.md deleted file mode 100644 index 6fc1fdd..0000000 --- a/generated/test/docs/k8s_ziti_controller_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/k8s_ziti_controller_params.md b/generated/test/docs/k8s_ziti_controller_params.md deleted file mode 100644 index 343d93e..0000000 --- a/generated/test/docs/k8s_ziti_controller_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Parameters - -- [Create params](k8s_ziti_controller_params_create.md) -- [Modify params](k8s_ziti_controller_params_modify.md) diff --git a/generated/test/docs/k8s_ziti_controller_params_create.md b/generated/test/docs/k8s_ziti_controller_params_create.md deleted file mode 100644 index dac54da..0000000 --- a/generated/test/docs/k8s_ziti_controller_params_create.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
298resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
294resource_cpuinteger300Квота ядра пода (milicores)minvalue=100; maxvalue=4000
295resource_memoryinteger512Квота памяти пода (MBytes)minvalue=128; maxvalue=8192
296resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
297resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
299domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
diff --git a/generated/test/docs/k8s_ziti_controller_params_modify.md b/generated/test/docs/k8s_ziti_controller_params_modify.md deleted file mode 100644 index 1998e6a..0000000 --- a/generated/test/docs/k8s_ziti_controller_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_k8s_ziti_controller - -Service ID: `88` - -Service Name: k8sZitiController - -[Manual](k8s_ziti_controller.md) | [Create params](k8s_ziti_controller_params_create.md) | [Modify params](k8s_ziti_controller_params_modify.md) | [Output params](k8s_ziti_controller_outputs.md) | [Operations](k8s_ziti_controller_ops.md) | [Example](k8s_ziti_controller_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/kafka.md b/generated/test/docs/kafka.md deleted file mode 100644 index 34f2d04..0000000 --- a/generated/test/docs/kafka.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## MAN - -
-# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Идентификатор организации
Уникальный идентификатор созданной организации. Используется для всех дальнейших API-операций.

### Статус организации
Отражает текущее состояние: active, suspended, modifying, deleting.

### Параметры сети
Выходные данные при наличии ipSpaces: список выделенных внешних IP, имя ip_space, количество IP.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)**;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к этой организации.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak.

-
diff --git a/generated/test/docs/kafka_example.md b/generated/test/docs/kafka_example.md deleted file mode 100644 index 4affd5e..0000000 --- a/generated/test/docs/kafka_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Copy-ready manifest (`kafka_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_kafka" "baza" { - resource_instances = 1 # Пример: `2` - resource_memory = 1 # Пример: `2048` - resource_cpu = 1 # Пример: `2000` - resource_disk = 1 # Пример: `20` - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - need_external_address_master = false # Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_kafka.baza.state_params["имя_ключа"] -nubes_kafka.baza.state_out["имя_ключа"] -nubes_kafka.baza.state_params_flat["имя_ключа"] -nubes_kafka.baza.state_out_flat["имя_ключа"] -nubes_kafka.baza.vault_secrets["имя_ключа"] -nubes_kafka.baza.vault_url -nubes_kafka.baza.vault_user_path -nubes_kafka.baza.vault_fields -``` diff --git a/generated/test/docs/kafka_ops.md b/generated/test/docs/kafka_ops.md deleted file mode 100644 index d21d9b4..0000000 --- a/generated/test/docs/kafka_ops.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](kafka_params_create.md) -- `create_topic` — # Инструкция по управлению топиками Apache Kafka через платформу ## 1. Общая информация --- Топик — это основная сущность в Apache Kafka, предназначенная для приёма сообщений от продюсеров и передачи их консюмерам. Платформа позволяет создавать, удалять и изменять параметры топиков без прямого доступа к брокерам, обеспечивая удобное управление через интерфейс или API. --- ## Доступные операции - **create_topic** — Создание топика - **modify_topic** — Модификация топика - **delete_topic** — Удаление топика --- ## 2. Параметры создания топика Ниже перечислены параметры, которые необходимо указать при создании нового топика: * **Имя топика** Название топика. Должно быть уникальным в пределах кластера. Пример: `orders-events`. * **Партиции** Количество партиций топика. Рекомендуется выбирать с учётом уровня параллелизма потребителей и предполагаемой нагрузки. Пример: `6`. Здесь важно рассказать о том как происходит расчет оптимального количества Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки. * **Реплики** Количество реплик для каждой партиции. Обычно равно количеству доступных брокеров или меньше. Пример: `3`. --- ## 4. Параметры модификации топика Для уже существующих топиков можно изменять параметры. Все параметры являются опциональными: * **Имя топика** Название топика. Пример: `orders-events`. * **Партиции** Новое количество партиций. Пример: `12`. * **Реплики** Новое количество реплик. Пример: `2`. --- ## 5. Рекомендации * Планируйте количество партиций с запасом — уменьшение их числа невозможно. * Количество реплик должно соответствовать требуемому уровню отказоустойчивости, но не превышать количество брокеров. * Изменение параметров топика в рабочем окружении может временно влиять на производительность. Рекомендуется проводить крупные изменения в периоды минимальной нагрузки. ---. См. [nubes_kafka_topic](kafka_topic.md) -- `create_user` — # Инструкция по управлению пользователями Apache Kafka. --- ## 1. Общая информация Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру. Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам. Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka. --- ## Доступные операции - **create_user** — Создание пользователя - **modify_user** — Модификация пользователя - **delete_user** — Удаление пользователя --- ## 2. Параметры создания пользователя Ниже перечислены параметры, которые необходимо указать при создании нового пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 3. Параметры модификации пользователя Ниже перечислены параметры, которые необходимо указать при модификации пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 4. Параметры удалении пользователя Ниже перечислены параметры, которые необходимо указать при удалении пользователя: * **Имя пользователя** Имя удаляемого пользователя. Пример: `username-admin` ## 5. Выходные параметры После успешного создания пользователя платформа возвращает параметры, необходимые для подключения: * **ca.crt** Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении. Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **ca.p12** PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.p12 ``` * **ca.password** Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно. * **user.crt** Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka. Используется совместно с приватным ключом `user.key` для аутентификации. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **user.key** Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.key ``` * **user.p12** PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo "<содержание поля>" | base64 -d > <название>.p12 ``` * **user.password** Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно. Эти параметры используются для настройки TLS-подключения. --- ## 6. Пример конфигурации клиента внутри кластера Пример пода: ```yaml apiVersion: v1 kind: Pod metadata: name: kafka-4 spec: volumes: - name: work emptyDir: {} containers: - name: kcat image: quay.io/strimzi/kafka:latest-kafka-4.0.0 command: ["sleep", "5600"] volumeMounts: - name: work mountPath: /work restartPolicy: Never ``` Создаём под и сохраняем сертификаты: ```bash kubectl cp user.p12 kafka-4:/work/ kubectl cp ca.p12 kafka-4:/work/ ``` Создаём файлы конфигурации: ```bash cat > /work/user-read.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` ```bash cat > /work/user-write.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user-write.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` Листинг доступных топиков: ```bash /opt/kafka/bin/kafka-topics.sh \ --bootstrap-server kafkak8s-bootstrap-external:9093 \ --command-config /work/user-read.properties \ --list ``` Запись сообщений: ```bash /opt/kafka/bin/kafka-console-producer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --producer.config /work/user-write.properties ``` Чтение сообщений: ```bash /opt/kafka/bin/kafka-console-consumer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --from-beginning \ --group \ --consumer.config /work/user-read.properties \ --max-messages 50 ``` --- ## 7. Пример внешнего подключения с использованием **kcat** **Листинг топиков** ```bash kcat -b :9093 \ -L \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` **Запись сообщения** ```bash echo "hello from kcat" | kcat -P \ -b :9093 \ -t write-test \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-write.crt \ -X ssl.key.location=./user-write.key \ -X ssl.endpoint.identification.algorithm=none ``` **Чтение сообщений** ```bash kcat -C \ -b :9093 \ -t write-test \ -o beginning \ -q \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` --- ## 9. Рекомендации * Минимизируйте набор разрешённых операций для повышения безопасности. * Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов. * Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**. * После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам. ---. См. [nubes_kafka_user](kafka_user.md) -- `delete` -- `delete_topic` — . См. [nubes_kafka_topic](kafka_topic.md) -- `delete_user` — # Инструкция по управлению пользователями Apache Kafka. --- ## 1. Общая информация Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру. Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам. Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka. --- ## Доступные операции - **create_user** — Создание пользователя - **modify_user** — Модификация пользователя - **delete_user** — Удаление пользователя --- ## 2. Параметры создания пользователя Ниже перечислены параметры, которые необходимо указать при создании нового пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 3. Параметры модификации пользователя Ниже перечислены параметры, которые необходимо указать при модификации пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 4. Параметры удалении пользователя Ниже перечислены параметры, которые необходимо указать при удалении пользователя: * **Имя пользователя** Имя удаляемого пользователя. Пример: `username-admin` ## 5. Выходные параметры После успешного создания пользователя платформа возвращает параметры, необходимые для подключения: * **ca.crt** Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении. Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **ca.p12** PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.p12 ``` * **ca.password** Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно. * **user.crt** Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka. Используется совместно с приватным ключом `user.key` для аутентификации. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **user.key** Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.key ``` * **user.p12** PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo "<содержание поля>" | base64 -d > <название>.p12 ``` * **user.password** Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно. Эти параметры используются для настройки TLS-подключения. --- ## 6. Пример конфигурации клиента внутри кластера Пример пода: ```yaml apiVersion: v1 kind: Pod metadata: name: kafka-4 spec: volumes: - name: work emptyDir: {} containers: - name: kcat image: quay.io/strimzi/kafka:latest-kafka-4.0.0 command: ["sleep", "5600"] volumeMounts: - name: work mountPath: /work restartPolicy: Never ``` Создаём под и сохраняем сертификаты: ```bash kubectl cp user.p12 kafka-4:/work/ kubectl cp ca.p12 kafka-4:/work/ ``` Создаём файлы конфигурации: ```bash cat > /work/user-read.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` ```bash cat > /work/user-write.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user-write.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` Листинг доступных топиков: ```bash /opt/kafka/bin/kafka-topics.sh \ --bootstrap-server kafkak8s-bootstrap-external:9093 \ --command-config /work/user-read.properties \ --list ``` Запись сообщений: ```bash /opt/kafka/bin/kafka-console-producer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --producer.config /work/user-write.properties ``` Чтение сообщений: ```bash /opt/kafka/bin/kafka-console-consumer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --from-beginning \ --group \ --consumer.config /work/user-read.properties \ --max-messages 50 ``` --- ## 7. Пример внешнего подключения с использованием **kcat** **Листинг топиков** ```bash kcat -b :9093 \ -L \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` **Запись сообщения** ```bash echo "hello from kcat" | kcat -P \ -b :9093 \ -t write-test \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-write.crt \ -X ssl.key.location=./user-write.key \ -X ssl.endpoint.identification.algorithm=none ``` **Чтение сообщений** ```bash kcat -C \ -b :9093 \ -t write-test \ -o beginning \ -q \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` --- ## 9. Рекомендации * Минимизируйте набор разрешённых операций для повышения безопасности. * Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов. * Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**. * После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам. ---. См. [nubes_kafka_user](kafka_user.md) -- `modify` — Изменение кластера. Параметры: [Modify params](kafka_params_modify.md) -- `modify_topic` — # Инструкция по управлению топиками Apache Kafka через платформу ## 1. Общая информация --- Топик — это основная сущность в Apache Kafka, предназначенная для приёма сообщений от продюсеров и передачи их консюмерам. Платформа позволяет создавать, удалять и изменять параметры топиков без прямого доступа к брокерам, обеспечивая удобное управление через интерфейс или API. --- ## Доступные операции - **create_topic** — Создание топика - **modify_topic** — Модификация топика - **delete_topic** — Удаление топика --- ## 2. Параметры создания топика Ниже перечислены параметры, которые необходимо указать при создании нового топика: * **Имя топика** Название топика. Должно быть уникальным в пределах кластера. Пример: `orders-events`. * **Партиции** Количество партиций топика. Рекомендуется выбирать с учётом уровня параллелизма потребителей и предполагаемой нагрузки. Пример: `6`. Здесь важно рассказать о том как происходит расчет оптимального количества Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки. * **Реплики** Количество реплик для каждой партиции. Обычно равно количеству доступных брокеров или меньше. Пример: `3`. --- ## 4. Параметры модификации топика Для уже существующих топиков можно изменять параметры. Все параметры являются опциональными: * **Имя топика** Название топика. Пример: `orders-events`. * **Партиции** Новое количество партиций. Пример: `12`. * **Реплики** Новое количество реплик. Пример: `2`. --- ## 5. Рекомендации * Планируйте количество партиций с запасом — уменьшение их числа невозможно. * Количество реплик должно соответствовать требуемому уровню отказоустойчивости, но не превышать количество брокеров. * Изменение параметров топика в рабочем окружении может временно влиять на производительность. Рекомендуется проводить крупные изменения в периоды минимальной нагрузки. ---. См. [nubes_kafka_topic](kafka_topic.md) -- `modify_user` — # Инструкция по управлению пользователями Apache Kafka. --- ## 1. Общая информация Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру. Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам. Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka. --- ## Доступные операции - **create_user** — Создание пользователя - **modify_user** — Модификация пользователя - **delete_user** — Удаление пользователя --- ## 2. Параметры создания пользователя Ниже перечислены параметры, которые необходимо указать при создании нового пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 3. Параметры модификации пользователя Ниже перечислены параметры, которые необходимо указать при модификации пользователя: * **Имя пользователя** Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав. Пример: `username-admin` * **Топик** Название топика, к которому будут назначены права для данного пользователя. Пример: `orders-events`. Использовать маску нельзя (`orders*`), только полное название или `*`. * **Операции** Список разрешённых операций на указанном топике. Пример: `Describe, Read, Write` * **Группа** Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп. Пример: `order-consumers`. * **Разрешённые хосты** Список хостов или подсетей, с которых разрешено подключение пользователя. Пример: `192.168.1.0/24` или `*`. --- ## 4. Параметры удалении пользователя Ниже перечислены параметры, которые необходимо указать при удалении пользователя: * **Имя пользователя** Имя удаляемого пользователя. Пример: `username-admin` ## 5. Выходные параметры После успешного создания пользователя платформа возвращает параметры, необходимые для подключения: * **ca.crt** Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении. Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **ca.p12** PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.p12 ``` * **ca.password** Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно. * **user.crt** Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka. Используется совместно с приватным ключом `user.key` для аутентификации. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.crt ``` * **user.key** Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo '<содержание поля>' | base64 -d > <название>.key ``` * **user.p12** PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka. Выдаеться в формате base64 для получения файла сертификата использовать команду ```bash echo "<содержание поля>" | base64 -d > <название>.p12 ``` * **user.password** Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно. Эти параметры используются для настройки TLS-подключения. --- ## 6. Пример конфигурации клиента внутри кластера Пример пода: ```yaml apiVersion: v1 kind: Pod metadata: name: kafka-4 spec: volumes: - name: work emptyDir: {} containers: - name: kcat image: quay.io/strimzi/kafka:latest-kafka-4.0.0 command: ["sleep", "5600"] volumeMounts: - name: work mountPath: /work restartPolicy: Never ``` Создаём под и сохраняем сертификаты: ```bash kubectl cp user.p12 kafka-4:/work/ kubectl cp ca.p12 kafka-4:/work/ ``` Создаём файлы конфигурации: ```bash cat > /work/user-read.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` ```bash cat > /work/user-write.properties <<'EOF' security.protocol=SSL ssl.keystore.type=PKCS12 ssl.keystore.location=/work/user-write.p12 ssl.keystore.password= ssl.truststore.type=PKCS12 ssl.truststore.location=/work/ca.p12 ssl.truststore.password= EOF ``` Листинг доступных топиков: ```bash /opt/kafka/bin/kafka-topics.sh \ --bootstrap-server kafkak8s-bootstrap-external:9093 \ --command-config /work/user-read.properties \ --list ``` Запись сообщений: ```bash /opt/kafka/bin/kafka-console-producer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --producer.config /work/user-write.properties ``` Чтение сообщений: ```bash /opt/kafka/bin/kafka-console-consumer.sh \ --bootstrap-server <адрес сервис брокера>:9093 \ --topic \ --from-beginning \ --group \ --consumer.config /work/user-read.properties \ --max-messages 50 ``` --- ## 7. Пример внешнего подключения с использованием **kcat** **Листинг топиков** ```bash kcat -b :9093 \ -L \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` **Запись сообщения** ```bash echo "hello from kcat" | kcat -P \ -b :9093 \ -t write-test \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-write.crt \ -X ssl.key.location=./user-write.key \ -X ssl.endpoint.identification.algorithm=none ``` **Чтение сообщений** ```bash kcat -C \ -b :9093 \ -t write-test \ -o beginning \ -q \ -X security.protocol=SSL \ -X ssl.ca.location=./ca.crt \ -X ssl.certificate.location=./user-read.crt \ -X ssl.key.location=./user-read.key \ -X ssl.endpoint.identification.algorithm=none ``` --- ## 9. Рекомендации * Минимизируйте набор разрешённых операций для повышения безопасности. * Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов. * Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**. * После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам. ---. См. [nubes_kafka_user](kafka_user.md) -- `resume` -- `suspend` diff --git a/generated/test/docs/kafka_outputs.md b/generated/test/docs/kafka_outputs.md deleted file mode 100644 index 7a36056..0000000 --- a/generated/test/docs/kafka_outputs.md +++ /dev/null @@ -1,54 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.bootstrap"]` -- `state_out_flat["externalConnect.bootstrap.fqdn"]` -- `state_out_flat["externalConnect.bootstrap.ip"]` -- `state_out_flat["externalConnect.bootstrap.isExternal"]` -- `state_out_flat["externalConnect.bootstrap.uuid"]` -- `state_out_flat["internalConnect"]` -- `state_out_flat["kafkaTopics"]` -- `state_out_flat["kafkaTopics.test-events"]` -- `state_out_flat["kafkaTopics.test-events.partitions"]` -- `state_out_flat["kafkaTopics.test-events.replicas"]` -- `state_out_flat["kafkaUsers"]` -- `state_out_flat["kafkaUsers.usertest"]` -- `state_out_flat["kafkaUsers.usertest.accessHosts"]` -- `state_out_flat["kafkaUsers.usertest.group"]` -- `state_out_flat["kafkaUsers.usertest.nameTopic"]` -- `state_out_flat["kafkaUsers.usertest.operations"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["users"]` - diff --git a/generated/test/docs/kafka_params.md b/generated/test/docs/kafka_params.md deleted file mode 100644 index 25cb573..0000000 --- a/generated/test/docs/kafka_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Parameters - -- [Create params](kafka_params_create.md) -- [Modify params](kafka_params_modify.md) diff --git a/generated/test/docs/kafka_params_create.md b/generated/test/docs/kafka_params_create.md deleted file mode 100644 index 1a43a4e..0000000 --- a/generated/test/docs/kafka_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
461resource_instancesintegerПример: `2`minvalue=1; value_list=1, 2, 3, 4, 5
462resource_memoryintegerПример: `2048`minvalue=1000
463resource_cpuintegerПример: `2000`minvalue=1000
464resource_diskintegerПример: `20`
466ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
469resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
465need_external_address_masterbooleanfalseФлаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`value_list=false, true
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/kafka_params_modify.md b/generated/test/docs/kafka_params_modify.md deleted file mode 100644 index e6ff431..0000000 --- a/generated/test/docs/kafka_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_kafka - -Service ID: `116` - -Service Name: ApacheKafka - -[Manual](kafka.md) | [Create params](kafka_params_create.md) | [Modify params](kafka_params_modify.md) | [Output params](kafka_outputs.md) | [Operations](kafka_ops.md) | [Example](kafka_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
501resource_instancesintegerПример: `2`value_list=1, 2, 3, 4, 5
502resource_memoryintegerПример: `2048`minvalue=1000
503resource_cpuПример: `2000`minvalue=1000
504resource_diskintegerПример: `20`
505need_external_address_masterbooleanФлаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`value_list=false, true
506ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
diff --git a/generated/test/docs/kafka_topic.md b/generated/test/docs/kafka_topic.md deleted file mode 100644 index e56d01e..0000000 --- a/generated/test/docs/kafka_topic.md +++ /dev/null @@ -1,35 +0,0 @@ -# Resource nubes_kafka_topic - -Service: `nubes_kafka` (ID: 116) - -[ApacheKafka (основной)](kafka.md) | [Operations](kafka_ops.md) | [Topic](kafka_topic.md) | [Example](kafka_topic_example.md) - -## Create params - -**Обязательные параметры** - - - - - - - -
IDCodeTypeDescriptionConstraints
523name_topicstringПример: `orders-events`
524partitionsintegerЧисло партиций можно увеличить, но уменьшить их нельзя.
525replicasintegerКоличество реплик не может привышать количество реплик брокера
- -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
526name_topicstringПример: `orders-events`
527partitionsЧисло партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50`
528replicasКоличество партиций ≤ (число брокеров). Пример `2`
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
529name_topicstringНеобходимо выбрать топик, который необходимо удалить
diff --git a/generated/test/docs/kafka_topic_example.md b/generated/test/docs/kafka_topic_example.md deleted file mode 100644 index 32af8ff..0000000 --- a/generated/test/docs/kafka_topic_example.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_kafka_topic — Example - -Service: `nubes_kafka` (ID: 116) - -[ApacheKafka (основной)](kafka.md) | [Operations](kafka_ops.md) | [Topic](kafka_topic.md) | [Example](kafka_topic_example.md) - -## Copy-ready manifest (`kafka_topic_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_kafka должен быть создан заранее -# resource "nubes_kafka" "baza" { ... } - -resource "nubes_kafka_topic" "example" { - kafka_id = nubes_kafka.baza.id - name_topic = "TODO" # Пример: `orders-events` - partitions = 1 # Число партиций можно увеличить, но уменьшить их нельзя. - replicas = 1 # Количество реплик не может привышать количество реплик брокера -} -``` diff --git a/generated/test/docs/kafka_user.md b/generated/test/docs/kafka_user.md deleted file mode 100644 index 46a21d0..0000000 --- a/generated/test/docs/kafka_user.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_kafka_user - -Service: `nubes_kafka` (ID: 116) - -[ApacheKafka (основной)](kafka.md) | [Operations](kafka_ops.md) | [User](kafka_user.md) | [Example](kafka_user_example.md) - -## Create params - -**Обязательные параметры** - - - - - - - - - -
IDCodeTypeDescriptionConstraints
530usernamestringПример: `username-admin`
531name_topicstringПример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`
532operationsstringПример: `Create, Describe, Read, Write`
533groupstringПример: `order-consumers` или `*`
534access_hostsstringПример: `192.168.1.0/24` или `*`
- -## Modify params - - - - - - - - - -
IDCodeTypeDescriptionConstraints
535name_topicstringПример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`
536operationsstringПример: `Create, Describe, Read, Write`
537groupstringПример: `order-consumers` или `*`
538access_hostsstringПример: `192.168.1.0/24` или `*`
539usernamestringПример: `username-admin`
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
540usernamestringПример: `username-admin`
diff --git a/generated/test/docs/kafka_user_example.md b/generated/test/docs/kafka_user_example.md deleted file mode 100644 index 28bada9..0000000 --- a/generated/test/docs/kafka_user_example.md +++ /dev/null @@ -1,35 +0,0 @@ -# Resource nubes_kafka_user — Example - -Service: `nubes_kafka` (ID: 116) - -[ApacheKafka (основной)](kafka.md) | [Operations](kafka_ops.md) | [User](kafka_user.md) | [Example](kafka_user_example.md) - -## Copy-ready manifest (`kafka_user_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_kafka должен быть создан заранее -# resource "nubes_kafka" "baza" { ... } - -resource "nubes_kafka_user" "example" { - kafka_id = nubes_kafka.baza.id - username = "TODO" # Пример: `username-admin` - name_topic = "TODO" # Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*` - operations = "TODO" # Пример: `Create, Describe, Read, Write` - group = "TODO" # Пример: `order-consumers` или `*` - access_hosts = "TODO" # Пример: `192.168.1.0/24` или `*` -} -``` diff --git a/generated/test/docs/lucee.md b/generated/test/docs/lucee.md deleted file mode 100644 index ca3542d..0000000 --- a/generated/test/docs/lucee.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/lucee_example.md b/generated/test/docs/lucee_example.md deleted file mode 100644 index 22320a4..0000000 --- a/generated/test/docs/lucee_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Copy-ready manifest (`lucee_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_lucee" "baza" { - startup_configuration = "TODO" - cluster_configuration = "TODO" - access_configuration = "TODO" - app_configuration = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - json_env = {} # Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_lucee.baza.state_params["имя_ключа"] -nubes_lucee.baza.state_out["имя_ключа"] -nubes_lucee.baza.state_params_flat["имя_ключа"] -nubes_lucee.baza.state_out_flat["имя_ключа"] -nubes_lucee.baza.vault_secrets["имя_ключа"] -nubes_lucee.baza.vault_url -nubes_lucee.baza.vault_user_path -nubes_lucee.baza.vault_fields -``` diff --git a/generated/test/docs/lucee_ops.md b/generated/test/docs/lucee_ops.md deleted file mode 100644 index a2e0373..0000000 --- a/generated/test/docs/lucee_ops.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](lucee_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](lucee_params_modify.md) -- `reconcile` -- `redeploy` -- `restart` -- `resume` -- `suspend` diff --git a/generated/test/docs/lucee_outputs.md b/generated/test/docs/lucee_outputs.md deleted file mode 100644 index 838f21d..0000000 --- a/generated/test/docs/lucee_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/test/docs/lucee_params.md b/generated/test/docs/lucee_params.md deleted file mode 100644 index 730e3b2..0000000 --- a/generated/test/docs/lucee_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Parameters - -- [Create params](lucee_params_create.md) -- [Modify params](lucee_params_modify.md) diff --git a/generated/test/docs/lucee_params_create.md b/generated/test/docs/lucee_params_create.md deleted file mode 100644 index 755d619..0000000 --- a/generated/test/docs/lucee_params_create.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
1019startup_configurationmap-fixed
1020cluster_configurationmap-fixed
1021access_configurationmap-fixed
1022app_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
1023json_envmap{}Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/lucee_params_modify.md b/generated/test/docs/lucee_params_modify.md deleted file mode 100644 index 4bda31b..0000000 --- a/generated/test/docs/lucee_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_lucee - -Service ID: `94` - -Service Name: Lucee - -[Manual](lucee.md) | [Create params](lucee_params_create.md) | [Modify params](lucee_params_modify.md) | [Output params](lucee_outputs.md) | [Operations](lucee_ops.md) | [Example](lucee_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
1024cluster_configurationmap-fixed
1025app_configurationmap-fixed
1026json_envmapПередаётся в формате КЛЮЧ:ЗНАЧЕНИЕ
diff --git a/generated/test/docs/mariadb.md b/generated/test/docs/mariadb.md deleted file mode 100644 index 9161094..0000000 --- a/generated/test/docs/mariadb.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## MAN - -
-Mariadb кластер. Ресурсная платформа: k8s. Автоматизация: k8s operator.
Автоматическое резервное копирование, ручное восстановление. -
diff --git a/generated/test/docs/mariadb_database.md b/generated/test/docs/mariadb_database.md deleted file mode 100644 index 092f130..0000000 --- a/generated/test/docs/mariadb_database.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_mariadb_database - -Service: `nubes_mariadb` (ID: 115) - -[Mariadb (основной)](mariadb.md) | [Operations](mariadb_ops.md) | [Database](mariadb_database.md) | [Example](mariadb_database_example.md) - -## Create params - -**Обязательные параметры** - -None. - -**Параметры со значением по умолчанию** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
734db_namestringdb-Пример: `db01`regex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
745db_namestringВСЕ ДАННЫЕ ВНУТРИ БД БУДУТ УДАЛЕНЫ
diff --git a/generated/test/docs/mariadb_database_example.md b/generated/test/docs/mariadb_database_example.md deleted file mode 100644 index 0cf5188..0000000 --- a/generated/test/docs/mariadb_database_example.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_mariadb_database — Example - -Service: `nubes_mariadb` (ID: 115) - -[Mariadb (основной)](mariadb.md) | [Operations](mariadb_ops.md) | [Database](mariadb_database.md) | [Example](mariadb_database_example.md) - -## Copy-ready manifest (`mariadb_database_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_mariadb должен быть создан заранее -# resource "nubes_mariadb" "baza" { ... } - -resource "nubes_mariadb_database" "example" { - mariadb_id = nubes_mariadb.baza.id - - # Параметры со значением по умолчанию - db_name = "db-" # Пример: `db01` -} -``` diff --git a/generated/test/docs/mariadb_example.md b/generated/test/docs/mariadb_example.md deleted file mode 100644 index e5ba3f5..0000000 --- a/generated/test/docs/mariadb_example.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Copy-ready manifest (`mariadb_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_mariadb" "baza" { - startup_configuration = "TODO" - cluster_configuration = "TODO" - access_configuration = "TODO" - mariadb_configuration = "TODO" - backup_configuration = "TODO" - autoscale_configuration = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_mariadb.baza.state_params["имя_ключа"] -nubes_mariadb.baza.state_out["имя_ключа"] -nubes_mariadb.baza.state_params_flat["имя_ключа"] -nubes_mariadb.baza.state_out_flat["имя_ключа"] -nubes_mariadb.baza.vault_secrets["имя_ключа"] -nubes_mariadb.baza.vault_url -nubes_mariadb.baza.vault_user_path -nubes_mariadb.baza.vault_fields -``` diff --git a/generated/test/docs/mariadb_ops.md b/generated/test/docs/mariadb_ops.md deleted file mode 100644 index 5ae1622..0000000 --- a/generated/test/docs/mariadb_ops.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](mariadb_params_create.md) -- `create_database` — . См. [nubes_mariadb_database](mariadb_database.md) -- `create_user` — . См. [nubes_mariadb_user](mariadb_user.md) -- `delete` -- `delete_database` — . См. [nubes_mariadb_database](mariadb_database.md) -- `delete_user` — . См. [nubes_mariadb_user](mariadb_user.md) -- `modify` — Изменение кластера. Параметры: [Modify params](mariadb_params_modify.md) -- `reconcile` -- `resume` -- `suspend` diff --git a/generated/test/docs/mariadb_outputs.md b/generated/test/docs/mariadb_outputs.md deleted file mode 100644 index 38f0606..0000000 --- a/generated/test/docs/mariadb_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/mariadb_params.md b/generated/test/docs/mariadb_params.md deleted file mode 100644 index 1d0477b..0000000 --- a/generated/test/docs/mariadb_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Parameters - -- [Create params](mariadb_params_create.md) -- [Modify params](mariadb_params_modify.md) diff --git a/generated/test/docs/mariadb_params_create.md b/generated/test/docs/mariadb_params_create.md deleted file mode 100644 index 2bc0c0a..0000000 --- a/generated/test/docs/mariadb_params_create.md +++ /dev/null @@ -1,37 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
877startup_configurationmap-fixed
878cluster_configurationmap-fixed
879access_configurationmap-fixed
880mariadb_configurationmap-fixed
881backup_configurationmap-fixed
882autoscale_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/mariadb_params_modify.md b/generated/test/docs/mariadb_params_modify.md deleted file mode 100644 index 65a66e7..0000000 --- a/generated/test/docs/mariadb_params_modify.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_mariadb - -Service ID: `115` - -Service Name: Mariadb - -[Manual](mariadb.md) | [Create params](mariadb_params_create.md) | [Modify params](mariadb_params_modify.md) | [Output params](mariadb_outputs.md) | [Operations](mariadb_ops.md) | [Example](mariadb_example.md) - -## Modify params - - - - - - - - - -
IDCodeTypeDescriptionConstraints
883cluster_configurationmap-fixed
884access_configurationmap-fixed
885mariadb_configurationmap-fixed
886backup_configurationmap-fixed
887autoscale_configurationmap-fixed
diff --git a/generated/test/docs/mariadb_user.md b/generated/test/docs/mariadb_user.md deleted file mode 100644 index c590f5e..0000000 --- a/generated/test/docs/mariadb_user.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_mariadb_user - -Service: `nubes_mariadb` (ID: 115) - -[Mariadb (основной)](mariadb.md) | [Operations](mariadb_ops.md) | [User](mariadb_user.md) | [Example](mariadb_user_example.md) - -## Create params - -**Обязательные параметры** - - - - - -
IDCodeTypeDescriptionConstraints
736passwordstringСекрет будет записан в хранилище секретов и не будет отображаться публичноmaxlength=62; minlength=8
- -**Параметры со значением по умолчанию** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
735usernamestringuserПример: `myusername`regex=^(?![0-9_])[a-zA-Z_][a-zA-Z0-9_]{0,62}$; maxlength=62; minlength=2
737db_namearray-map-fixed[{}]Если базы не существует - при выполнении операции вернётся ошибка
738access_hostsstring%Пример: `%`
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
744usernamestringИмя пользователя, созданное через операцию `create_user`
diff --git a/generated/test/docs/mariadb_user_example.md b/generated/test/docs/mariadb_user_example.md deleted file mode 100644 index e16d466..0000000 --- a/generated/test/docs/mariadb_user_example.md +++ /dev/null @@ -1,36 +0,0 @@ -# Resource nubes_mariadb_user — Example - -Service: `nubes_mariadb` (ID: 115) - -[Mariadb (основной)](mariadb.md) | [Operations](mariadb_ops.md) | [User](mariadb_user.md) | [Example](mariadb_user_example.md) - -## Copy-ready manifest (`mariadb_user_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_mariadb должен быть создан заранее -# resource "nubes_mariadb" "baza" { ... } - -resource "nubes_mariadb_user" "example" { - mariadb_id = nubes_mariadb.baza.id - password = "TODO" # Секрет будет записан в хранилище секретов и не будет отображаться публично - - # Параметры со значением по умолчанию - username = "user" # Пример: `myusername` - db_name = [{}] # Необходимо указать массив существующих баз - access_hosts = "%" # Пример: `%` -} -``` diff --git a/generated/test/docs/mongodb.md b/generated/test/docs/mongodb.md deleted file mode 100644 index 3502e9e..0000000 --- a/generated/test/docs/mongodb.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## MAN - -
-# Инструкция по развертыванию MongoDB через платформу

## 1. Общая информация

MongoDB — документоориентированная распределённая база данных, обеспечивающая высокую доступность, горизонтальное масштабирование и гибкую модель хранения.

### Доступные операции с кластером

* **create** — создание базы
* **delete** — удаление базы данных
* **suspend** — остановка базы данных
* **resume** — запуск базы данных
* **modify** — изменение базы данных

### Доступные операции с пользователями

* **create_user** — создание пользователя
* **modify_user** — модификация пользователя
* **delete_user** — удаление пользователя

---

## 2. Параметры развертывания базы данных

Эти параметры необходимо указать при создании базы данных.

### Платформа для развертывания

Среда, в которой будет развернут кластер. Выбирается из предложенного списка.

### Количество узлов

Количество реплик в кластере MongoDB.
Оптимально выбирать нечётное значение, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность базы данных даже при отказе одной из нод.

> **Примечание:** уменьшение количества узлов после создания кластера не рекомендуется.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных в гигабайтах.
Пример: `20`

### Имя ipSpace для публикации внешнего IP

Имя ipSpace, через который будет выделен внешний IP для доступа к master-узлу.
Укажите `no-needed`, если внешний адрес не требуется.
Пример: `internet-no-antiddos-v1`

### Список разрешённых IP-адресов

Список IP-адресов или подсетей, с которых разрешён доступ к кластеру.
Если оставить пустым — доступ открыт для всех источников.
Пример: `["10.0.0.0/24", "192.168.1.10/32"]`

---

## 3. Параметры модификации базы данных

Все параметры, которые вы указываете при модификации, являются необязательными — система автоматически подставит ранее сохранённые значения, и при необходимости вы можете изменить их на нужные.

### Количество узлов

Количество реплик в кластере MongoDB.
Оптимально выбирать нечётное значение, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность базы данных даже при отказе одной из нод.

> **Примечание:** уменьшение количества узлов после создания кластера не рекомендуется.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных указывается в гигабайтах. Его можно увеличить при необходимости, однако уменьшить уже выделенный размер невозможно.
Пример: `20`

### Имя ipSpace для публикации внешнего IP

Имя ipSpace, через который будет выделен внешний IP для доступа к master-узлу.
Укажите `no-needed`, если внешний адрес не требуется.
Пример: `internet-no-antiddos-v1`

### Список разрешённых IP-адресов

Список IP-адресов или подсетей, с которых разрешён доступ к кластеру.
Если оставить пустым — доступ открыт для всех источников.
Пример: `["10.0.0.0/24", "192.168.1.10/32"]`

---

## 3. Параметры создания пользователя

### Имя пользователя

Указывается имя пользователя (любой регистр).
Пример: `readApp`

### Имя базы данных

Название базы, в которой будет создан пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read** — доступ только на чтение
* **readWrite** — чтение и изменение данных
* **dbOwner** — полный контроль над базой данных

---

## 4. Параметры модификации пользователя

### Имя пользователя

Необходимо выбрать существующего пользователя.
Если список пуст, требуется предварительно создать пользователя.

### Имя базы данных

База данных, к которой относится пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read**
* **readWrite**
* **dbOwner**

---

## 5. Параметры удаления пользователя

### Имя пользователя

Выберите пользователя из списка для удаления.

---

## 6. Выходные параметры

После успешного развертывания базы данных платформа возвращает ключевые параметры.

### internalConnect

Внутренний эндпоинт для подключения к кластеру из сервисов, работающих в той же сети.
Используется для внутренних интеграций и системных сервисов.

### externalConnect

Внешний FQDN для подключения к кластеру извне.
Порт подключения — **27017**.

---

## 7. Пример подключения

Перед подключением необходимо установить **mongosh**.

Команда подключения к базе данных:

```
mongosh "mongodb://<username>:<password>@<endpoint_db>:27017/<dbName>"
```

Где:

* `<username>` — имя пользователя
* `<password>` — пароль
* `<endpoint_db>` — internalConnect или externalConnect
* `<dbName>` — имя базы данных

## 8. Дополнительная информация

Сейчас соединение с базой работает без шифрования, и доступ к кластеру осуществляется только по логину и паролю. -
diff --git a/generated/test/docs/mongodb_example.md b/generated/test/docs/mongodb_example.md deleted file mode 100644 index 895b483..0000000 --- a/generated/test/docs/mongodb_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Copy-ready manifest (`mongodb_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_mongodb" "baza" { - resource_instances = 1 # Пример: `2` - resource_memory = 1 # Пример: `2048` - resource_cpu = 1 # Пример: `1000` - resource_disk = 1 # Пример: `20` - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - master_access_list = [] # Список IP-адресов, с которых разрешён доступ. Если оставить пустым — доступ открыт всем. -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_mongodb.baza.state_params["имя_ключа"] -nubes_mongodb.baza.state_out["имя_ключа"] -nubes_mongodb.baza.state_params_flat["имя_ключа"] -nubes_mongodb.baza.state_out_flat["имя_ключа"] -nubes_mongodb.baza.vault_secrets["имя_ключа"] -nubes_mongodb.baza.vault_url -nubes_mongodb.baza.vault_user_path -nubes_mongodb.baza.vault_fields -``` diff --git a/generated/test/docs/mongodb_ops.md b/generated/test/docs/mongodb_ops.md deleted file mode 100644 index fb06e5b..0000000 --- a/generated/test/docs/mongodb_ops.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](mongodb_params_create.md) -- `create_user` — . См. [nubes_mongodb_user](mongodb_user.md) -- `delete` -- `delete_user` — . См. [nubes_mongodb_user](mongodb_user.md) -- `modify` — Изменение кластера. Параметры: [Modify params](mongodb_params_modify.md) -- `modify_user` — . См. [nubes_mongodb_user](mongodb_user.md) -- `resume` -- `suspend` diff --git a/generated/test/docs/mongodb_outputs.md b/generated/test/docs/mongodb_outputs.md deleted file mode 100644 index 2a6b2dc..0000000 --- a/generated/test/docs/mongodb_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["internalConnect"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/test/docs/mongodb_params.md b/generated/test/docs/mongodb_params.md deleted file mode 100644 index b595ec1..0000000 --- a/generated/test/docs/mongodb_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Parameters - -- [Create params](mongodb_params_create.md) -- [Modify params](mongodb_params_modify.md) diff --git a/generated/test/docs/mongodb_params_create.md b/generated/test/docs/mongodb_params_create.md deleted file mode 100644 index 4cfcb00..0000000 --- a/generated/test/docs/mongodb_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
487resource_instancesintegerПример: `2`minvalue=1; maxvalue=7
588resource_memoryintegerПример: `2048`minvalue=512
589resource_cpuintegerПример: `1000`
590resource_diskintegerПример: `20`
595resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
646ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
889master_access_listjson[]Передаётся как массив строк. Пример: [&quot;192.168.0.0&quot;, &quot;192.168.0.1&quot;]
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/mongodb_params_modify.md b/generated/test/docs/mongodb_params_modify.md deleted file mode 100644 index 9bff5f5..0000000 --- a/generated/test/docs/mongodb_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_mongodb - -Service ID: `92` - -Service Name: MongoDB - -[Manual](mongodb.md) | [Create params](mongodb_params_create.md) | [Modify params](mongodb_params_modify.md) | [Output params](mongodb_outputs.md) | [Operations](mongodb_ops.md) | [Example](mongodb_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
648resource_instancesintegerПример: `2`
649resource_memoryintegerПример: `2048`minvalue=512
650resource_cpuintegerПример: `1000`minvalue=500
651resource_diskintegerПример: `20`
653ip_space_name_masterstringЕсли включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`
890master_access_listjsonПередаётся как массив строк. Пример: [&quot;192.168.0.0&quot;, &quot;192.168.0.1&quot;]
diff --git a/generated/test/docs/mongodb_user.md b/generated/test/docs/mongodb_user.md deleted file mode 100644 index ece4f31..0000000 --- a/generated/test/docs/mongodb_user.md +++ /dev/null @@ -1,35 +0,0 @@ -# Resource nubes_mongodb_user - -Service: `nubes_mongodb` (ID: 92) - -[MongoDB (основной)](mongodb.md) | [Operations](mongodb_ops.md) | [User](mongodb_user.md) | [Example](mongodb_user_example.md) - -## Create params - -**Обязательные параметры** - - - - - - - -
IDCodeTypeDescriptionConstraints
635usernamestring
636db_namestring
643rolestringvalue_list=dbOwner, read, readWrite
- -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
640usernamestring
641db_namestring
642rolestringvalue_list=dbOwner, read, readWrite
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
644usernamestring
diff --git a/generated/test/docs/mongodb_user_example.md b/generated/test/docs/mongodb_user_example.md deleted file mode 100644 index e59f2c4..0000000 --- a/generated/test/docs/mongodb_user_example.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_mongodb_user — Example - -Service: `nubes_mongodb` (ID: 92) - -[MongoDB (основной)](mongodb.md) | [Operations](mongodb_ops.md) | [User](mongodb_user.md) | [Example](mongodb_user_example.md) - -## Copy-ready manifest (`mongodb_user_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_mongodb должен быть создан заранее -# resource "nubes_mongodb" "baza" { ... } - -resource "nubes_mongodb_user" "example" { - mongodb_id = nubes_mongodb.baza.id - username = "TODO" - db_name = "TODO" - role = "dbOwner" -} -``` diff --git a/generated/test/docs/nextcloud.md b/generated/test/docs/nextcloud.md deleted file mode 100644 index a494623..0000000 --- a/generated/test/docs/nextcloud.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## MAN - -
-Ресурсная платформа: k8s. Автоматизация: helm chart -
diff --git a/generated/test/docs/nextcloud_backup.md b/generated/test/docs/nextcloud_backup.md deleted file mode 100644 index 4145cbb..0000000 --- a/generated/test/docs/nextcloud_backup.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_nextcloud_backup - -Service: `nubes_nextcloud` (ID: 50) - -[Nextcloud (основной)](nextcloud.md) | [Operations](nextcloud_ops.md) | [Backup](nextcloud_backup.md) | [Example](nextcloud_backup_example.md) - -## Create params - -**Обязательные параметры** - - - - - -
IDCodeTypeDescriptionConstraints
1077startup_configurationmap-fixed
- -## Delete params - -None. diff --git a/generated/test/docs/nextcloud_backup_example.md b/generated/test/docs/nextcloud_backup_example.md deleted file mode 100644 index 53c1b33..0000000 --- a/generated/test/docs/nextcloud_backup_example.md +++ /dev/null @@ -1,31 +0,0 @@ -# Resource nubes_nextcloud_backup — Example - -Service: `nubes_nextcloud` (ID: 50) - -[Nextcloud (основной)](nextcloud.md) | [Operations](nextcloud_ops.md) | [Backup](nextcloud_backup.md) | [Example](nextcloud_backup_example.md) - -## Copy-ready manifest (`nextcloud_backup_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_nextcloud должен быть создан заранее -# resource "nubes_nextcloud" "baza" { ... } - -resource "nubes_nextcloud_backup" "example" { - nextcloud_id = nubes_nextcloud.baza.id - startup_configuration = "TODO" -} -``` diff --git a/generated/test/docs/nextcloud_example.md b/generated/test/docs/nextcloud_example.md deleted file mode 100644 index abbc7a1..0000000 --- a/generated/test/docs/nextcloud_example.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Copy-ready manifest (`nextcloud_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_nextcloud" "baza" { - startup_configuration = "TODO" - cluster_configuration = "TODO" - access_configuration = "TODO" - app_configuration = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nextcloud.baza.state_params["имя_ключа"] -nubes_nextcloud.baza.state_out["имя_ключа"] -nubes_nextcloud.baza.state_params_flat["имя_ключа"] -nubes_nextcloud.baza.state_out_flat["имя_ключа"] -nubes_nextcloud.baza.vault_secrets["имя_ключа"] -nubes_nextcloud.baza.vault_url -nubes_nextcloud.baza.vault_user_path -nubes_nextcloud.baza.vault_fields -``` diff --git a/generated/test/docs/nextcloud_ops.md b/generated/test/docs/nextcloud_ops.md deleted file mode 100644 index 47b0bce..0000000 --- a/generated/test/docs/nextcloud_ops.md +++ /dev/null @@ -1,19 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nextcloud_params_create.md) -- `create_backup` — Перед запуском обязательно надо перевести экземпляр Nextcloud в статус 'suspended'. См. [nubes_nextcloud_backup](nextcloud_backup.md) -- `delete` — DEV-Ветка удаления Nextcloud -- `modify` — Изменение кластера. Параметры: [Modify params](nextcloud_params_modify.md) -- `reconcile` -- `recovery` -- `restart` -- `resume` -- `suspend` diff --git a/generated/test/docs/nextcloud_outputs.md b/generated/test/docs/nextcloud_outputs.md deleted file mode 100644 index 1a8707b..0000000 --- a/generated/test/docs/nextcloud_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/nextcloud_params.md b/generated/test/docs/nextcloud_params.md deleted file mode 100644 index 2c1eb71..0000000 --- a/generated/test/docs/nextcloud_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Parameters - -- [Create params](nextcloud_params_create.md) -- [Modify params](nextcloud_params_modify.md) diff --git a/generated/test/docs/nextcloud_params_create.md b/generated/test/docs/nextcloud_params_create.md deleted file mode 100644 index c6723ab..0000000 --- a/generated/test/docs/nextcloud_params_create.md +++ /dev/null @@ -1,35 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
1055startup_configurationmap-fixed
1056cluster_configurationmap-fixed
1057access_configurationmap-fixed
1058app_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/nextcloud_params_modify.md b/generated/test/docs/nextcloud_params_modify.md deleted file mode 100644 index 47d56d1..0000000 --- a/generated/test/docs/nextcloud_params_modify.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_nextcloud - -Service ID: `50` - -Service Name: Nextcloud - -[Manual](nextcloud.md) | [Create params](nextcloud_params_create.md) | [Modify params](nextcloud_params_modify.md) | [Output params](nextcloud_outputs.md) | [Operations](nextcloud_ops.md) | [Example](nextcloud_example.md) - -## Modify params - - - - - - -
IDCodeTypeDescriptionConstraints
1059cluster_configurationmap-fixed
1060app_configurationmap-fixed
diff --git a/generated/test/docs/nifi.md b/generated/test/docs/nifi.md deleted file mode 100644 index cf2c590..0000000 --- a/generated/test/docs/nifi.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/nifi_example.md b/generated/test/docs/nifi_example.md deleted file mode 100644 index 0897886..0000000 --- a/generated/test/docs/nifi_example.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Copy-ready manifest (`nifi_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_nifi" "baza" { - kafka_uid = "TODO" # Выбрать кластер из списка - partitions = 1 # Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - replicas = 1 # Количество партиций ≤ (число брокеров). Пример `2` - name_topic = "TODO" # Пример: `orders-events` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nifi.baza.state_params["имя_ключа"] -nubes_nifi.baza.state_out["имя_ключа"] -nubes_nifi.baza.state_params_flat["имя_ключа"] -nubes_nifi.baza.state_out_flat["имя_ключа"] -nubes_nifi.baza.vault_secrets["имя_ключа"] -nubes_nifi.baza.vault_url -nubes_nifi.baza.vault_user_path -nubes_nifi.baza.vault_fields -``` diff --git a/generated/test/docs/nifi_ops.md b/generated/test/docs/nifi_ops.md deleted file mode 100644 index a896c6a..0000000 --- a/generated/test/docs/nifi_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nifi_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](nifi_params_modify.md) diff --git a/generated/test/docs/nifi_outputs.md b/generated/test/docs/nifi_outputs.md deleted file mode 100644 index 976b25e..0000000 --- a/generated/test/docs/nifi_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/nifi_params.md b/generated/test/docs/nifi_params.md deleted file mode 100644 index 4dcadac..0000000 --- a/generated/test/docs/nifi_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Parameters - -- [Create params](nifi_params_create.md) -- [Modify params](nifi_params_modify.md) diff --git a/generated/test/docs/nifi_params_create.md b/generated/test/docs/nifi_params_create.md deleted file mode 100644 index d5c4baa..0000000 --- a/generated/test/docs/nifi_params_create.md +++ /dev/null @@ -1,23 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
471kafka_uiduuidВыбрать кластер из спискаref_svc_id=116
472partitionsintegerОбратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.
473replicasintegerКоличество партиций ≤ (число брокеров). Пример `2`
474name_topicstringПример: `orders-events`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/test/docs/nifi_params_modify.md b/generated/test/docs/nifi_params_modify.md deleted file mode 100644 index 7f34ef0..0000000 --- a/generated/test/docs/nifi_params_modify.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_nifi - -Service ID: `117` - -Service Name: Nifi - -[Manual](nifi.md) | [Create params](nifi_params_create.md) | [Modify params](nifi_params_modify.md) | [Output params](nifi_outputs.md) | [Operations](nifi_ops.md) | [Example](nifi_example.md) - -## Modify params - - - - - - -
IDCodeTypeDescriptionConstraints
477partitionsintegerОбратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.
478replicasintegerКоличество партиций ≤ (число брокеров). Пример `2`
diff --git a/generated/test/docs/nodejs.md b/generated/test/docs/nodejs.md deleted file mode 100644 index a1c6804..0000000 --- a/generated/test/docs/nodejs.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## MAN - -
-Развертывает контейнер в k8s кластере с node, который можно использовать для запуска своих приложений.
Приложение должно быть доступно по ссылки в git репозитории, которая является входным параметром. -
diff --git a/generated/test/docs/nodejs_example.md b/generated/test/docs/nodejs_example.md deleted file mode 100644 index 3bfda9f..0000000 --- a/generated/test/docs/nodejs_example.md +++ /dev/null @@ -1,49 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Copy-ready manifest (`nodejs_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_nodejs" "baza" { - startup_configuration = "TODO" - cluster_configuration = "TODO" - access_configuration = "TODO" - app_configuration = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - json_env = {} # Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nodejs.baza.state_params["имя_ключа"] -nubes_nodejs.baza.state_out["имя_ключа"] -nubes_nodejs.baza.state_params_flat["имя_ключа"] -nubes_nodejs.baza.state_out_flat["имя_ключа"] -nubes_nodejs.baza.vault_secrets["имя_ключа"] -nubes_nodejs.baza.vault_url -nubes_nodejs.baza.vault_user_path -nubes_nodejs.baza.vault_fields -``` diff --git a/generated/test/docs/nodejs_ops.md b/generated/test/docs/nodejs_ops.md deleted file mode 100644 index 46c51e1..0000000 --- a/generated/test/docs/nodejs_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nodejs_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](nodejs_params_modify.md) -- `reconcile` -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/test/docs/nodejs_outputs.md b/generated/test/docs/nodejs_outputs.md deleted file mode 100644 index 5fa8a14..0000000 --- a/generated/test/docs/nodejs_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/test/docs/nodejs_params.md b/generated/test/docs/nodejs_params.md deleted file mode 100644 index daf96ca..0000000 --- a/generated/test/docs/nodejs_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Parameters - -- [Create params](nodejs_params_create.md) -- [Modify params](nodejs_params_modify.md) diff --git a/generated/test/docs/nodejs_params_create.md b/generated/test/docs/nodejs_params_create.md deleted file mode 100644 index 6151786..0000000 --- a/generated/test/docs/nodejs_params_create.md +++ /dev/null @@ -1,39 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - -
IDCodeTypeDescriptionConstraints
1028startup_configurationmap-fixed
1029cluster_configurationmap-fixed
1030access_configurationmap-fixed
1031app_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
1032json_envmap{}Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/nodejs_params_modify.md b/generated/test/docs/nodejs_params_modify.md deleted file mode 100644 index b0158e2..0000000 --- a/generated/test/docs/nodejs_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_nodejs - -Service ID: `95` - -Service Name: NodeJS - -[Manual](nodejs.md) | [Create params](nodejs_params_create.md) | [Modify params](nodejs_params_modify.md) | [Output params](nodejs_outputs.md) | [Operations](nodejs_ops.md) | [Example](nodejs_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
1033cluster_configurationmap-fixed
1034app_configurationmap-fixed
1035json_envmapПередаётся в формате КЛЮЧ:ЗНАЧЕНИЕ
diff --git a/generated/test/docs/nodered.md b/generated/test/docs/nodered.md deleted file mode 100644 index 54ecff3..0000000 --- a/generated/test/docs/nodered.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/nodered_example.md b/generated/test/docs/nodered_example.md deleted file mode 100644 index 554f430..0000000 --- a/generated/test/docs/nodered_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Copy-ready manifest (`nodered_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_nodered" "baza" { - resource_realm = "TODO" # Платформа для развертывания - domain = "TODO" # Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_nodered.baza.state_params["имя_ключа"] -nubes_nodered.baza.state_out["имя_ключа"] -nubes_nodered.baza.state_params_flat["имя_ключа"] -nubes_nodered.baza.state_out_flat["имя_ключа"] -nubes_nodered.baza.vault_secrets["имя_ключа"] -nubes_nodered.baza.vault_url -nubes_nodered.baza.vault_user_path -nubes_nodered.baza.vault_fields -``` diff --git a/generated/test/docs/nodered_ops.md b/generated/test/docs/nodered_ops.md deleted file mode 100644 index 2d6074e..0000000 --- a/generated/test/docs/nodered_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](nodered_params_create.md) -- `delete` diff --git a/generated/test/docs/nodered_outputs.md b/generated/test/docs/nodered_outputs.md deleted file mode 100644 index 74e4213..0000000 --- a/generated/test/docs/nodered_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/nodered_params.md b/generated/test/docs/nodered_params.md deleted file mode 100644 index 60a797d..0000000 --- a/generated/test/docs/nodered_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Parameters - -- [Create params](nodered_params_create.md) -- [Modify params](nodered_params_modify.md) diff --git a/generated/test/docs/nodered_params_create.md b/generated/test/docs/nodered_params_create.md deleted file mode 100644 index f976ccb..0000000 --- a/generated/test/docs/nodered_params_create.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
196resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
197domainstringНаименование поддомена, будет добавлено в k8stemplate.dev.nubes.ruregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
193resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=100; maxvalue=4000
194resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
195resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
323resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
diff --git a/generated/test/docs/nodered_params_modify.md b/generated/test/docs/nodered_params_modify.md deleted file mode 100644 index be00f3b..0000000 --- a/generated/test/docs/nodered_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_nodered - -Service ID: `97` - -Service Name: NodeRed - -[Manual](nodered.md) | [Create params](nodered_params_create.md) | [Modify params](nodered_params_modify.md) | [Output params](nodered_outputs.md) | [Operations](nodered_ops.md) | [Example](nodered_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/openwhisk.md b/generated/test/docs/openwhisk.md deleted file mode 100644 index 059ed46..0000000 --- a/generated/test/docs/openwhisk.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## MAN - -
-Добавление и удаления пользователя для работы с Openwhisk -
diff --git a/generated/test/docs/openwhisk_example.md b/generated/test/docs/openwhisk_example.md deleted file mode 100644 index 0eda09d..0000000 --- a/generated/test/docs/openwhisk_example.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Copy-ready manifest (`openwhisk_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_openwhisk" "baza" { -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_openwhisk.baza.state_params["имя_ключа"] -nubes_openwhisk.baza.state_out["имя_ключа"] -nubes_openwhisk.baza.state_params_flat["имя_ключа"] -nubes_openwhisk.baza.state_out_flat["имя_ключа"] -nubes_openwhisk.baza.vault_secrets["имя_ключа"] -nubes_openwhisk.baza.vault_url -nubes_openwhisk.baza.vault_user_path -nubes_openwhisk.baza.vault_fields -``` diff --git a/generated/test/docs/openwhisk_ops.md b/generated/test/docs/openwhisk_ops.md deleted file mode 100644 index e931c78..0000000 --- a/generated/test/docs/openwhisk_ops.md +++ /dev/null @@ -1,10 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Operations - diff --git a/generated/test/docs/openwhisk_outputs.md b/generated/test/docs/openwhisk_outputs.md deleted file mode 100644 index e2cdfe5..0000000 --- a/generated/test/docs/openwhisk_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/openwhisk_params.md b/generated/test/docs/openwhisk_params.md deleted file mode 100644 index 1a9b0e5..0000000 --- a/generated/test/docs/openwhisk_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Parameters - -- [Create params](openwhisk_params_create.md) -- [Modify params](openwhisk_params_modify.md) diff --git a/generated/test/docs/openwhisk_params_create.md b/generated/test/docs/openwhisk_params_create.md deleted file mode 100644 index f6d47cf..0000000 --- a/generated/test/docs/openwhisk_params_create.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - -None. - -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/test/docs/openwhisk_params_modify.md b/generated/test/docs/openwhisk_params_modify.md deleted file mode 100644 index 7791043..0000000 --- a/generated/test/docs/openwhisk_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_openwhisk - -Service ID: `100` - -Service Name: Serverless Openwhisk (openwhisk_tenant) - -[Manual](openwhisk.md) | [Create params](openwhisk_params_create.md) | [Modify params](openwhisk_params_modify.md) | [Output params](openwhisk_outputs.md) | [Operations](openwhisk_ops.md) | [Example](openwhisk_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/pgadmin.md b/generated/test/docs/pgadmin.md deleted file mode 100644 index 5c2feaf..0000000 --- a/generated/test/docs/pgadmin.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## MAN - -
-Инструмент с графическим интерфейсом для управления базами данных PostgreSQL -
diff --git a/generated/test/docs/pgadmin_example.md b/generated/test/docs/pgadmin_example.md deleted file mode 100644 index 8366795..0000000 --- a/generated/test/docs/pgadmin_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Copy-ready manifest (`pgadmin_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_pgadmin" "baza" { - resource_realm = "TODO" # Платформа для развертывания - login = "TODO" # Логин для подключения к pgAdmin, в формате email (login@email.net) - password = "TODO" # Пароль для подключения к pgAdmin - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - resource_cpu = 500 # Квота ядра пода (milicores). 1000Mili = 1 Ядро - resource_memory = 512 # Квота памяти пода (MBytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_pgadmin.baza.state_params["имя_ключа"] -nubes_pgadmin.baza.state_out["имя_ключа"] -nubes_pgadmin.baza.state_params_flat["имя_ключа"] -nubes_pgadmin.baza.state_out_flat["имя_ключа"] -nubes_pgadmin.baza.vault_secrets["имя_ключа"] -nubes_pgadmin.baza.vault_url -nubes_pgadmin.baza.vault_user_path -nubes_pgadmin.baza.vault_fields -``` diff --git a/generated/test/docs/pgadmin_ops.md b/generated/test/docs/pgadmin_ops.md deleted file mode 100644 index 7449f5e..0000000 --- a/generated/test/docs/pgadmin_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](pgadmin_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](pgadmin_params_modify.md) -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/test/docs/pgadmin_outputs.md b/generated/test/docs/pgadmin_outputs.md deleted file mode 100644 index a88297a..0000000 --- a/generated/test/docs/pgadmin_outputs.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["connectionUrl"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - diff --git a/generated/test/docs/pgadmin_params.md b/generated/test/docs/pgadmin_params.md deleted file mode 100644 index 3afd95c..0000000 --- a/generated/test/docs/pgadmin_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Parameters - -- [Create params](pgadmin_params_create.md) -- [Modify params](pgadmin_params_modify.md) diff --git a/generated/test/docs/pgadmin_params_create.md b/generated/test/docs/pgadmin_params_create.md deleted file mode 100644 index f87da9c..0000000 --- a/generated/test/docs/pgadmin_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
169resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
170loginstringЛогин для подключения к pgAdmin, в формате email (login@email.net)regex=^([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)$; maxlength=255; minlength=3
171passwordstringПароль для подключения к pgAdmin
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
164domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$; unique_scope=provider
165resource_cpuinteger500Квота ядра пода (milicores). 1000Mili = 1 Ядроminvalue=500; maxvalue=4000
166resource_memoryinteger512Квота памяти пода (MBytes)minvalue=512; maxvalue=8192
167resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/pgadmin_params_modify.md b/generated/test/docs/pgadmin_params_modify.md deleted file mode 100644 index 28c4957..0000000 --- a/generated/test/docs/pgadmin_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_pgadmin - -Service ID: `96` - -Service Name: pgAdmin - -[Manual](pgadmin.md) | [Create params](pgadmin_params_create.md) | [Modify params](pgadmin_params_modify.md) | [Output params](pgadmin_outputs.md) | [Operations](pgadmin_ops.md) | [Example](pgadmin_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
172resource_cpuintegerКвота ядра пода (Указывается в mili). 1000Mili = 1 Ядроminvalue=500; maxvalue=4000
173resource_memoryintegerКвота памяти пода (MBytes)minvalue=512; maxvalue=8192
174resource_diskintegerКвота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
diff --git a/generated/test/docs/postgres.md b/generated/test/docs/postgres.md deleted file mode 100644 index 61e7668..0000000 --- a/generated/test/docs/postgres.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## MAN - -
-# Инструкция по развертыванию PostgreSQL через платформу

---
## 1. Общая информация

PostgreSQL — это надёжная объектно-реляционная СУБД с открытым исходным кодом, поддерживающая расширенный набор функций, транзакции и хранение сложных типов данных. Развёртывание полностью автоматизировано платформой на базе Zalando Postgres Operator с использованием Kubernetes.

## Доступные операции

- **create** — Создание кластера
- **delete** — Удаление кластера
- **modify** — Модификация кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера
- **restart** — Перезапуск кластера
- **recovery** — Восстановление из резервной копии

- **create_user** — Создание пользователя
- **delete_user** — Удаление пользователя

- **create_database** — Создание базы данных
- **delete_database** — Удаление базы данных


---
## 2. Параметры развертывания кластера

Ниже перечислены параметры, которые необходимо указать при создании ресурса PostgreSQL:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество инстансов (реплик) в кластере PostgreSQL. Пример: `2` (master + slave).

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных в гигабайтах. Пример: `20`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`

* **Выделяет внешний IP для доступа к slave:**
Флаг для выделения внешнего IP для slave (реплики чтения). Работает, если slave присутствует в кластере.

* **Имя ipSpace для публикации внешнего IP slave:**
Если включен параметр для slave, то поле необходимо заполнить.

* **UUID экземпляра услуги S3:**
UUID экземпляра S3 для хранения резервных копий.

* **Версия PostgreSQL:**
Версия PostgreSQL для развертывания. Пример: `16`

* **Расписание бэкапов (ext_BACKUP_SCHEDULE):**
Необязательный. Cron-выражение для времени запуска бэкапов. По умолчанию: `0 0 * * *` (ежедневно в полночь).

* **Количество сохраняемых бэкапов (ext_BACKUP_NUM_TO_RETAIN):**
Необязательный. Количество сохраняемых бэкапов. По умолчанию: `7`

* **PgPooler (master / slave):**
Флаги включения PgBouncer для подключений на запись и чтение. При включении создаётся отдельный под.

* **Разрешить подключение без SSL (allowNoSSL):**
По умолчанию подключение с sslmode=require. При `true` разрешается подключение без SSL.

* **Автоскейлинг PV (autoScale):**
Включает автоскейлинг тома. Требует настройки autoScalePercentage, autoScaleTechWindow, autoScaleQuotaGb.

* **Дополнительные параметры PostgreSQL (jsonParameters):**
JSON с переменными конфигурации PostgreSQL. Документация: https://www.postgresql.org/docs/current/runtime-config.html

---
## 3. Выходные параметры

После успешного развертывания ресурса PostgreSQL платформа возвращает ряд параметров.

#### externalConnect

Внешние эндпоинты для подключения к кластеру:
- **master** — для операций записи (host: `write.${namespace}`, port: 5432)
- **slave** — для операций чтения (host: `read.${namespace}`, port: 5432)

Пример ответа платформы:

```json
{
"slave": {
"ip": "",
"fqdn": "",
"uuid": "",
"isExternal": false
},
"master": {
"ip": "<ip>",
"fqdn": "write.<namespace>.<cluster-domain>",
"uuid": "<uuid>",
"isExternal": false
}
}
```

Поля: `ip` — внешний IP; `fqdn` — полное имя хоста; `uuid` — идентификатор; `isExternal` — признак внешнего доступа.

#### internalConnect

Внутренние эндпоинты (FQDN) для подключения из других сервисов внутри той же сети Kubernetes.

Пример ответа платформы:

```json
{
"slave": "",
"master": {
"slave": "",
"master": {
"slave": "",
"master": "postgresqlk8s-master.<namespace>.svc.cluster.local"
}
}
}
```

Для подключения используйте значение `master.master.master` (host для записи) или соответствующее значение slave (host для чтения).

Для подключения используется порт **5432**.

---
## 4. Управление пользователями

### create_user — Создание пользователя

* **Имя пользователя (username):**
Имя создаваемого пользователя. Используется для подключения к базе и настройки прав.
Пример: `myapp_user`

* **Роль (role):**
Тип роли пользователя. Допустимые значения:
- `app_user` — базовые права для DML-операций (SELECT, INSERT, UPDATE, DELETE)
- `ddl_user` — расширенные права: createdb, createrole (управление базами и ролями)

Защищённые имена, которые нельзя использовать: `admin`, `postgres`, `standby`.

### delete_user — Удаление пользователя

* **Имя пользователя (username):**
Имя удаляемого пользователя. Пример: `myapp_user`

Пользователя нельзя удалить, если он является владельцем базы данных. Сначала удалите или передайте владение базами данных другому пользователю.

---
## 5. Управление базами данных

### create_database — Создание базы данных

* **Имя базы данных (dbName):**
Название создаваемой базы данных. Пример: `myapp_db`

* **Владелец базы данных (dbOwner):**
Имя пользователя-владельца базы. Должен существовать в кластере (создан через create_user). Пример: `myapp_user`

### delete_database — Удаление базы данных

* **Имя базы данных (dbName):**
Название удаляемой базы данных. Пример: `myapp_db`
-
diff --git a/generated/test/docs/postgres_backup.md b/generated/test/docs/postgres_backup.md deleted file mode 100644 index 96074ea..0000000 --- a/generated/test/docs/postgres_backup.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_postgres_backup - -Service: `nubes_postgres` (ID: 90) - -[PostgreSQL (основной)](postgres.md) | [Operations](postgres_ops.md) | [Backup](postgres_backup.md) | [Example](postgres_backup_example.md) - -## Create params - -None. - -## Delete params - -None. diff --git a/generated/test/docs/postgres_backup_example.md b/generated/test/docs/postgres_backup_example.md deleted file mode 100644 index a49493b..0000000 --- a/generated/test/docs/postgres_backup_example.md +++ /dev/null @@ -1,30 +0,0 @@ -# Resource nubes_postgres_backup — Example - -Service: `nubes_postgres` (ID: 90) - -[PostgreSQL (основной)](postgres.md) | [Operations](postgres_ops.md) | [Backup](postgres_backup.md) | [Example](postgres_backup_example.md) - -## Copy-ready manifest (`postgres_backup_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_postgres должен быть создан заранее -# resource "nubes_postgres" "baza" { ... } - -resource "nubes_postgres_backup" "example" { - postgres_id = nubes_postgres.baza.id -} -``` diff --git a/generated/test/docs/postgres_database.md b/generated/test/docs/postgres_database.md deleted file mode 100644 index af1dd78..0000000 --- a/generated/test/docs/postgres_database.md +++ /dev/null @@ -1,24 +0,0 @@ -# Resource nubes_postgres_database - -Service: `nubes_postgres` (ID: 90) - -[PostgreSQL (основной)](postgres.md) | [Operations](postgres_ops.md) | [Database](postgres_database.md) | [Example](postgres_database_example.md) - -## Create params - -**Обязательные параметры** - - - - - - -
IDCodeTypeDescriptionConstraints
741db_namestringregex=^[A-Za-z0-9]+$
742db_ownerstring
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
743db_namestring
diff --git a/generated/test/docs/postgres_database_example.md b/generated/test/docs/postgres_database_example.md deleted file mode 100644 index 083d2f8..0000000 --- a/generated/test/docs/postgres_database_example.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_postgres_database — Example - -Service: `nubes_postgres` (ID: 90) - -[PostgreSQL (основной)](postgres.md) | [Operations](postgres_ops.md) | [Database](postgres_database.md) | [Example](postgres_database_example.md) - -## Copy-ready manifest (`postgres_database_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_postgres должен быть создан заранее -# resource "nubes_postgres" "baza" { ... } - -resource "nubes_postgres_database" "example" { - postgres_id = nubes_postgres.baza.id - db_name = "TODO" - db_owner = "TODO" -} -``` diff --git a/generated/test/docs/postgres_example.md b/generated/test/docs/postgres_example.md deleted file mode 100644 index 961c1b8..0000000 --- a/generated/test/docs/postgres_example.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Copy-ready manifest (`postgres_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_postgres" "baza" { - cluster_configuration = "TODO" - startup_configuration = "TODO" - access_configuration = "TODO" - postgres_configuration = "TODO" - backup_configuration = "TODO" - autoscale_configuration = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_postgres.baza.state_params["имя_ключа"] -nubes_postgres.baza.state_out["имя_ключа"] -nubes_postgres.baza.state_params_flat["имя_ключа"] -nubes_postgres.baza.state_out_flat["имя_ключа"] -nubes_postgres.baza.vault_secrets["имя_ключа"] -nubes_postgres.baza.vault_url -nubes_postgres.baza.vault_user_path -nubes_postgres.baza.vault_fields -``` diff --git a/generated/test/docs/postgres_ops.md b/generated/test/docs/postgres_ops.md deleted file mode 100644 index cc2703c..0000000 --- a/generated/test/docs/postgres_ops.md +++ /dev/null @@ -1,23 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](postgres_params_create.md) -- `create_backup` — . См. [nubes_postgres_backup](postgres_backup.md) -- `create_database` — . См. [nubes_postgres_database](postgres_database.md) -- `create_user` — . См. [nubes_postgres_user](postgres_user.md) -- `delete` -- `delete_database` — . См. [nubes_postgres_database](postgres_database.md) -- `delete_user` — . См. [nubes_postgres_user](postgres_user.md) -- `modify` — Изменение кластера. Параметры: [Modify params](postgres_params_modify.md) -- `reconcile` -- `recovery` -- `restart` — ВНИМАНИЕ - Рестарт предполагает УДАЛЕНИЕ подов. Может быть полная поломка. Крайне осторожно запускать при работе -- `resume` -- `suspend` diff --git a/generated/test/docs/postgres_outputs.md b/generated/test/docs/postgres_outputs.md deleted file mode 100644 index f07b697..0000000 --- a/generated/test/docs/postgres_outputs.md +++ /dev/null @@ -1,65 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.master"]` -- `state_out_flat["externalConnect.master.fqdn"]` -- `state_out_flat["externalConnect.master.ip"]` -- `state_out_flat["externalConnect.master.isExternal"]` -- `state_out_flat["externalConnect.master.uuid"]` -- `state_out_flat["externalConnect.slave"]` -- `state_out_flat["externalConnect.slave.fqdn"]` -- `state_out_flat["externalConnect.slave.ip"]` -- `state_out_flat["externalConnect.slave.isExternal"]` -- `state_out_flat["externalConnect.slave.uuid"]` -- `state_out_flat["internalConnect"]` -- `state_out_flat["internalConnect.master"]` -- `state_out_flat["internalConnect.slave"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.k8spostgresql"]` -- `state_out_flat["monitoring.k8spostgresql.url"]` -- `state_out_flat["monitoring.k8spostgresqlbackup"]` -- `state_out_flat["monitoring.k8spostgresqlbackup.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` -- `vault_secrets["standbyPass"]` -- `vault_secrets["standbyUser"]` - -### Пример для связки с Lucee/NodeJS - -```hcl -testds_connectionString = "jdbc:postgresql://${nubes_postgres.db2.state_out_flat["internalConnect.master"]}:5432/postgres?sslmode=require" -testds_username = nubes_postgres.db2.vault_secrets["adminUser"] -testds_password = nubes_postgres.db2.vault_secrets["adminPass"] -``` diff --git a/generated/test/docs/postgres_params.md b/generated/test/docs/postgres_params.md deleted file mode 100644 index b44e9f4..0000000 --- a/generated/test/docs/postgres_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Parameters - -- [Create params](postgres_params_create.md) -- [Modify params](postgres_params_modify.md) diff --git a/generated/test/docs/postgres_params_create.md b/generated/test/docs/postgres_params_create.md deleted file mode 100644 index 8957e32..0000000 --- a/generated/test/docs/postgres_params_create.md +++ /dev/null @@ -1,38 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
788cluster_configurationmap-fixed
789startup_configurationmap-fixed
790access_configurationmap-fixed
791postgres_configurationmap-fixed
792postgres_confarray-map-fixed
793backup_configurationmap-fixed
794autoscale_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/postgres_params_modify.md b/generated/test/docs/postgres_params_modify.md deleted file mode 100644 index 5a67a37..0000000 --- a/generated/test/docs/postgres_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_postgres - -Service ID: `90` - -Service Name: PostgreSQL - -[Manual](postgres.md) | [Create params](postgres_params_create.md) | [Modify params](postgres_params_modify.md) | [Output params](postgres_outputs.md) | [Operations](postgres_ops.md) | [Example](postgres_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
795cluster_configurationmap-fixed
796access_configurationmap-fixed
797postgres_configurationmap-fixed
798postgres_confarray-map-fixed
799backup_configurationmap-fixed
800autoscale_configurationmap-fixed
diff --git a/generated/test/docs/postgres_user.md b/generated/test/docs/postgres_user.md deleted file mode 100644 index e82e589..0000000 --- a/generated/test/docs/postgres_user.md +++ /dev/null @@ -1,24 +0,0 @@ -# Resource nubes_postgres_user - -Service: `nubes_postgres` (ID: 90) - -[PostgreSQL (основной)](postgres.md) | [Operations](postgres_ops.md) | [User](postgres_user.md) | [Example](postgres_user_example.md) - -## Create params - -**Обязательные параметры** - - - - - - -
IDCodeTypeDescriptionConstraints
733usernamestringregex=^[A-Za-z0-9]+$; maxlength=62; minlength=2
740rolestring`app_user` — стандартный пользователь с базовым набором прав
`ddl_user` — пользователь с расширенными правами, включая управление ролями и базами данных
value_list=app_user, ddl_user
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
739usernamestringПример: `username-admin`
diff --git a/generated/test/docs/postgres_user_example.md b/generated/test/docs/postgres_user_example.md deleted file mode 100644 index 9aa11f2..0000000 --- a/generated/test/docs/postgres_user_example.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_postgres_user — Example - -Service: `nubes_postgres` (ID: 90) - -[PostgreSQL (основной)](postgres.md) | [Operations](postgres_ops.md) | [User](postgres_user.md) | [Example](postgres_user_example.md) - -## Copy-ready manifest (`postgres_user_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_postgres должен быть создан заранее -# resource "nubes_postgres" "baza" { ... } - -resource "nubes_postgres_user" "example" { - postgres_id = nubes_postgres.baza.id - username = "TODO" - role = "app_user" # Выбрать роль из списка -} -``` diff --git a/generated/test/docs/rabbitmq.md b/generated/test/docs/rabbitmq.md deleted file mode 100644 index d0e5af3..0000000 --- a/generated/test/docs/rabbitmq.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## MAN - -
-# Инструкция по развертыванию RabbitMQ через платформу

---
## 1. Общая информация
RabbitMQ — это брокер сообщений с открытым исходным кодом, который обеспечивает надёжную доставку сообщений между приложениями.
Позволяет надёжно передавать сообщения между сервисами и системами, интегрироваться с внешними решениями и использовать как внутренние, так и защищённые TLS-подключения. Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание кластера
- **modify** — Изменение параметров кластера
- **delete** — Удаление кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера


---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса RabbitMQ:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество реплик в кластере RabbitMQ. При значении больше 1 создаётся кластер с репликацией для обеспечения высокой доступности.
Пример: `1` (single node) или `3` (кластер с репликацией)

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных RabbitMQ в гигабайтах. Пример: `50`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-узлу. При включении создаётся Service типа LoadBalancer и настраивается VIP на порту 5672.
Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`


---
## 3. Модификация кластера
Операция **modify** позволяет изменить параметры существующего кластера RabbitMQ.

**Изменяемые параметры:**
* **Квота (megabyte) памяти пода** — можно увеличить или уменьшить
* **Квота (millicore) ядра пода** — можно увеличить или уменьшить
* **Размер (gigabyte) диска для базы данных** — можно только увеличить (уменьшение не поддерживается)
* **Количество узлов в сети** — можно только увеличить (уменьшение не поддерживается)
* **Выделяет внешний IP для доступа к master** — можно включить или выключить
* **Имя ipSpace для публикации внешнего IP master** — можно изменить при включенном внешнем IP

**Ограничения:**
* Уменьшение размера диска не поддерживается
* Уменьшение количества реплик не поддерживается

---
## 4. Выходные параметры
После успешного развертывания ресурса RabbitMQ платформа возвращает ряд параметров в разделе "Поля состояния (сгенерированные значения)":

**clusterDomain**
Домен кластера Kubernetes, в котором развернут RabbitMQ.
Пример: `cluster.local`

**inernalConnect**
Внутренние эндпоинты для подключения к кластеру RabbitMQ из других сервисов, развернутых внутри той же сети.
Содержит:
* **master** — FQDN для подключения к кластеру. Пример: `rabbitmqk8s.{namespace}.svc.{clusterDomain}`

**externalConnect**
Внешние эндпоинты для подключения к кластеру RabbitMQ извне.
Содержит объекты с полями:
* **admin** — доступ к веб-интерфейсу управления:
* `fqdn` — полное доменное имя для веб-интерфейса. Пример: `admin.{namespace}.{domain}`
* `ip` — IP-адрес
* **master** — доступ к AMQP протоколу (если включен внешний IP):
* `fqdn` — полное доменное имя для AMQP. Пример: `write.{namespace}.{domain}`
* `ip` — IP-адрес

**monitoring**
Информация о дашбордах мониторинга:
* **allDashboards** — URL для доступа ко всем дашбордам Grafana

Для подключения используются следующие порты:

* **5672** — AMQP протокол (внутренний и внешний доступ, если включен внешний IP)
* **15672** — веб-интерфейс управления (доступен через Ingress по HTTPS)

**Учётные данные**
Данные для подключения к RabbitMQ доступны в разделе "Учётные данные":
* **adminUser** — имя пользователя администратора
* **adminPass** — пароль администратора


---
## 5. Примеры подключения через консоль (rabbitmqadmin)

### Работа с очередями через rabbitmqadmin

Для работы с RabbitMQ через консоль используется утилита `rabbitmqadmin`. Установите её или используйте образ с предустановленной утилитой.

Задайте переменные окружения с учётными данными:

```bash
export RABBITMQ_USERNAME=<adminUser>
export RABBITMQ_PASSWORD=<adminPass>
export RABBIT_HOST=<host>
```

Где:
* `<adminUser>` и `<adminPass>` — учётные данные из раздела "Учётные данные"
* `<host>` — адрес для подключения:
* Для внешнего подключения: `externalConnect.admin.fqdn` или `externalConnect.master.fqdn`

**Создание очереди:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
declare queue name=healthcheck durable=false
```

**Листинг очередей:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
list queues
```

**Отправка сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
publish exchange=amq.default routing_key=healthcheck payload="ping-$(date +%s)"
```

**Чтение сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
get queue=healthcheck ackmode=ack_requeue_false
```

---
## 6. Дополнительная информация
Для подключения к кластеру RabbitMQ используйте полученные эндпоинты из раздела "Поля состояния (сгенерированные значения)" и учётные данные из раздела "Учётные данные".

Веб-интерфейс управления доступен по адресу, указанному в параметре `externalConnect.admin.fqdn` через HTTPS.

Для внутреннего подключения используйте адрес из `inernalConnect.master` на порту 5672.

--- -
diff --git a/generated/test/docs/rabbitmq_example.md b/generated/test/docs/rabbitmq_example.md deleted file mode 100644 index 1c955b9..0000000 --- a/generated/test/docs/rabbitmq_example.md +++ /dev/null @@ -1,50 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Copy-ready manifest (`rabbitmq_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_rabbitmq" "baza" { - resource_realm = "TODO" # Выбрать платформу из списка - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - resource_cpu = 1000 # Пример: `2000` - resource_memory = 1124 # Пример: `2048` - resource_disk = 30 # Пример: `20` - resource_instances = 1 # Пример: `1` - need_external_address_master = false # Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_rabbitmq.baza.state_params["имя_ключа"] -nubes_rabbitmq.baza.state_out["имя_ключа"] -nubes_rabbitmq.baza.state_params_flat["имя_ключа"] -nubes_rabbitmq.baza.state_out_flat["имя_ключа"] -nubes_rabbitmq.baza.vault_secrets["имя_ключа"] -nubes_rabbitmq.baza.vault_url -nubes_rabbitmq.baza.vault_user_path -nubes_rabbitmq.baza.vault_fields -``` diff --git a/generated/test/docs/rabbitmq_ops.md b/generated/test/docs/rabbitmq_ops.md deleted file mode 100644 index fe63cf6..0000000 --- a/generated/test/docs/rabbitmq_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](rabbitmq_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](rabbitmq_params_modify.md) -- `resume` -- `suspend` — Пока не работает из за того что RabbitmqCluster нельзя занулить diff --git a/generated/test/docs/rabbitmq_outputs.md b/generated/test/docs/rabbitmq_outputs.md deleted file mode 100644 index 30d870e..0000000 --- a/generated/test/docs/rabbitmq_outputs.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["clusterDomain"]` -- `state_out_flat["externalConnect"]` -- `state_out_flat["externalConnect.admin"]` -- `state_out_flat["externalConnect.admin.fqdn"]` -- `state_out_flat["externalConnect.admin.ip"]` -- `state_out_flat["externalConnect.admin.isExternal"]` -- `state_out_flat["externalConnect.admin.uuid"]` -- `state_out_flat["inernalConnect"]` -- `state_out_flat["inernalConnect.master"]` -- `state_out_flat["inernalConnect.slave"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.base"]` -- `state_out_flat["monitoring.base.url"]` -- `state_out_flat["monitoring.loki"]` -- `state_out_flat["monitoring.loki.url"]` - -### `vault_secrets` ключи - -- `vault_secrets["adminPass"]` -- `vault_secrets["adminUser"]` - diff --git a/generated/test/docs/rabbitmq_params.md b/generated/test/docs/rabbitmq_params.md deleted file mode 100644 index b743d18..0000000 --- a/generated/test/docs/rabbitmq_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Parameters - -- [Create params](rabbitmq_params_create.md) -- [Modify params](rabbitmq_params_modify.md) diff --git a/generated/test/docs/rabbitmq_params_create.md b/generated/test/docs/rabbitmq_params_create.md deleted file mode 100644 index 1a1b21f..0000000 --- a/generated/test/docs/rabbitmq_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
119resource_realmstringВыбрать платформу из спискаfunc=getAvailableResourceRealms
543ip_space_name_masterstringПример: `internet-no-antiddos-v1`
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
116resource_cpuinteger1000Пример: `2000`minvalue=500; maxvalue=4000
117resource_memoryinteger1124Пример: `2048`minvalue=512; maxvalue=8192
118resource_diskinteger30Пример: `20`minvalue=5; maxvalue=999
224resource_instancesinteger1Пример: `1`minvalue=1; maxvalue=7
225need_external_address_masterbooleanfalseФлаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`value_list=false, true
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/rabbitmq_params_modify.md b/generated/test/docs/rabbitmq_params_modify.md deleted file mode 100644 index 6df624c..0000000 --- a/generated/test/docs/rabbitmq_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_rabbitmq - -Service ID: `93` - -Service Name: RabbitMQ - -[Manual](rabbitmq.md) | [Create params](rabbitmq_params_create.md) | [Modify params](rabbitmq_params_modify.md) | [Output params](rabbitmq_outputs.md) | [Operations](rabbitmq_ops.md) | [Example](rabbitmq_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
304resource_cpuintegerПример: `2000`minvalue=500; maxvalue=4000
305resource_memoryintegerПример: `2048`minvalue=512; maxvalue=8192
306resource_diskintegerПример: `20`minvalue=1; maxvalue=999
307resource_instancesintegerПример: `1`minvalue=1; maxvalue=7
308need_external_address_masterbooleanВыделяет внешний (белый) IP для доступа к mastervalue_list=false, true
545ip_space_name_masterstringПример: `internet-no-antiddos-v1`
diff --git a/generated/test/docs/redis.md b/generated/test/docs/redis.md deleted file mode 100644 index 4dfd2ea..0000000 --- a/generated/test/docs/redis.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## MAN - -
-Redis кластер. Под кеши.
Ресурсная платформа: k8s.
Автоматизация: k8s operator
port 6379 -
diff --git a/generated/test/docs/redis_example.md b/generated/test/docs/redis_example.md deleted file mode 100644 index 559e7f4..0000000 --- a/generated/test/docs/redis_example.md +++ /dev/null @@ -1,45 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Copy-ready manifest (`redis_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_redis" "baza" { - startup_configuration = "TODO" - cluster_configuration = "TODO" - access_configuration = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_redis.baza.state_params["имя_ключа"] -nubes_redis.baza.state_out["имя_ключа"] -nubes_redis.baza.state_params_flat["имя_ключа"] -nubes_redis.baza.state_out_flat["имя_ключа"] -nubes_redis.baza.vault_secrets["имя_ключа"] -nubes_redis.baza.vault_url -nubes_redis.baza.vault_user_path -nubes_redis.baza.vault_fields -``` diff --git a/generated/test/docs/redis_ops.md b/generated/test/docs/redis_ops.md deleted file mode 100644 index 4156679..0000000 --- a/generated/test/docs/redis_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](redis_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](redis_params_modify.md) -- `reconcile` -- `resume` -- `suspend` diff --git a/generated/test/docs/redis_outputs.md b/generated/test/docs/redis_outputs.md deleted file mode 100644 index c735f67..0000000 --- a/generated/test/docs/redis_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/redis_params.md b/generated/test/docs/redis_params.md deleted file mode 100644 index 131dd5e..0000000 --- a/generated/test/docs/redis_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Parameters - -- [Create params](redis_params_create.md) -- [Modify params](redis_params_modify.md) diff --git a/generated/test/docs/redis_params_create.md b/generated/test/docs/redis_params_create.md deleted file mode 100644 index 2eff875..0000000 --- a/generated/test/docs/redis_params_create.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
1061startup_configurationmap-fixed
1062cluster_configurationmap-fixed
1063access_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/redis_params_modify.md b/generated/test/docs/redis_params_modify.md deleted file mode 100644 index b4ed8a0..0000000 --- a/generated/test/docs/redis_params_modify.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_redis - -Service ID: `91` - -Service Name: Redis - -[Manual](redis.md) | [Create params](redis_params_create.md) | [Modify params](redis_params_modify.md) | [Output params](redis_outputs.md) | [Operations](redis_ops.md) | [Example](redis_example.md) - -## Modify params - - - - - - -
IDCodeTypeDescriptionConstraints
1064cluster_configurationmap-fixed
1065access_configurationmap-fixed
diff --git a/generated/test/docs/s3.md b/generated/test/docs/s3.md deleted file mode 100644 index 15a87a0..0000000 --- a/generated/test/docs/s3.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## MAN - -
-Руководство доступно по ссылке:
https://docs.s3.msk-1.ngcloud.ru/s3/s3.description.html -
diff --git a/generated/test/docs/s3_example.md b/generated/test/docs/s3_example.md deleted file mode 100644 index 2c54570..0000000 --- a/generated/test/docs/s3_example.md +++ /dev/null @@ -1,44 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Copy-ready manifest (`s3_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_s3" "baza" { - resource_realm = "TODO" # Платформа для развертывания - display_name = "TODO" # Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_s3.baza.state_params["имя_ключа"] -nubes_s3.baza.state_out["имя_ключа"] -nubes_s3.baza.state_params_flat["имя_ключа"] -nubes_s3.baza.state_out_flat["имя_ключа"] -nubes_s3.baza.vault_secrets["имя_ключа"] -nubes_s3.baza.vault_url -nubes_s3.baza.vault_user_path -nubes_s3.baza.vault_fields -``` diff --git a/generated/test/docs/s3_ops.md b/generated/test/docs/s3_ops.md deleted file mode 100644 index 655b982..0000000 --- a/generated/test/docs/s3_ops.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](s3_params_create.md) -- `create_sub_user` — . См. [nubes_s3_sub_user](s3_sub_user.md) -- `delete` -- `delete_sub_user` — . См. [nubes_s3_sub_user](s3_sub_user.md) -- `modify` — Изменение кластера. Параметры: [Modify params](s3_params_modify.md) -- `reconcile` -- `resume` -- `suspend` diff --git a/generated/test/docs/s3_outputs.md b/generated/test/docs/s3_outputs.md deleted file mode 100644 index e1cdeb2..0000000 --- a/generated/test/docs/s3_outputs.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["dtEndTrial"]` -- `state_out_flat["dtStartTrial"]` -- `state_out_flat["isTrial"]` -- `state_out_flat["monitoring"]` -- `state_out_flat["monitoring.allDashboards"]` -- `state_out_flat["monitoring.s3ceph"]` -- `state_out_flat["monitoring.s3ceph.url"]` -- `state_out_flat["urlConnect"]` - -### `vault_secrets` ключи - -- `vault_secrets["1325_access_key"]` -- `vault_secrets["1325_secret_key"]` -- `vault_secrets["1325_technicalS3Backup_access_key"]` -- `vault_secrets["1325_technicalS3Backup_secret_key"]` - diff --git a/generated/test/docs/s3_params.md b/generated/test/docs/s3_params.md deleted file mode 100644 index d61aced..0000000 --- a/generated/test/docs/s3_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Parameters - -- [Create params](s3_params_create.md) -- [Modify params](s3_params_modify.md) diff --git a/generated/test/docs/s3_params_create.md b/generated/test/docs/s3_params_create.md deleted file mode 100644 index b9a9364..0000000 --- a/generated/test/docs/s3_params_create.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
163resource_realmкластер S3 для подключенияfunc=getAvailableResourceRealms
320display_namestringЧеловеко-читаемое имя (транслит из Elma) - передаётся имя клиентаregex=^[a-zA-Z0-9_]{1,61}[a-zA-Z0-9]$
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/s3_params_modify.md b/generated/test/docs/s3_params_modify.md deleted file mode 100644 index d5a1da0..0000000 --- a/generated/test/docs/s3_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_s3 - -Service ID: `12` - -Service Name: S3 Object Storage - -[Manual](s3.md) | [Create params](s3_params_create.md) | [Modify params](s3_params_modify.md) | [Output params](s3_outputs.md) | [Operations](s3_ops.md) | [Example](s3_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
50max_size_gb_per_userintegermaxSizeGb. Передаём рукамиminvalue=1; maxvalue=50000
51max_objects_per_bucketintegerКвота на бакет. Кол-во объектов. Передаём рукамиminvalue=1; maxvalue=10000000
52max_buckets_per_userintegerКвота на пользователя. Количество бакетов пользователя. Передаём рукамиminvalue=1; maxvalue=1000
diff --git a/generated/test/docs/s3_sub_user.md b/generated/test/docs/s3_sub_user.md deleted file mode 100644 index 1975010..0000000 --- a/generated/test/docs/s3_sub_user.md +++ /dev/null @@ -1,24 +0,0 @@ -# Resource nubes_s3_sub_user - -Service: `nubes_s3` (ID: 12) - -[S3 Object Storage (основной)](s3.md) | [Operations](s3_ops.md) | [Sub_user](s3_sub_user.md) | [Example](s3_sub_user_example.md) - -## Create params - -**Обязательные параметры** - - - - - - -
IDCodeTypeDescriptionConstraints
60sub_user_namestring
61sub_user_accessstringvalue_list=read, write, readwrite, full
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
63sub_user_namestringsubUserName. По идее услуга уже создана - должен передаваться из ЛК
diff --git a/generated/test/docs/s3_sub_user_example.md b/generated/test/docs/s3_sub_user_example.md deleted file mode 100644 index b0634b7..0000000 --- a/generated/test/docs/s3_sub_user_example.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_s3_sub_user — Example - -Service: `nubes_s3` (ID: 12) - -[S3 Object Storage (основной)](s3.md) | [Operations](s3_ops.md) | [Sub_user](s3_sub_user.md) | [Example](s3_sub_user_example.md) - -## Copy-ready manifest (`s3_sub_user_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_s3 должен быть создан заранее -# resource "nubes_s3" "baza" { ... } - -resource "nubes_s3_sub_user" "example" { - s3_id = nubes_s3.baza.id - sub_user_name = "TODO" - sub_user_access = "read" -} -``` diff --git a/generated/test/docs/s3bucket.md b/generated/test/docs/s3bucket.md deleted file mode 100644 index 27d17d7..0000000 --- a/generated/test/docs/s3bucket.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/s3bucket_example.md b/generated/test/docs/s3bucket_example.md deleted file mode 100644 index 7233482..0000000 --- a/generated/test/docs/s3bucket_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Copy-ready manifest (`s3bucket_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_s3bucket" "baza" { - s3_user_uid = "TODO" # UID Корневой услуги S3. На основе него будет создан бакет. - bucket_name = "TODO" # Имя бакета s3 - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - max_size = -1 # Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes - read_all = false # Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. - list_all = false # Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. - cors_all = false # Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS - placement = "HOT" # Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_s3bucket.baza.state_params["имя_ключа"] -nubes_s3bucket.baza.state_out["имя_ключа"] -nubes_s3bucket.baza.state_params_flat["имя_ключа"] -nubes_s3bucket.baza.state_out_flat["имя_ключа"] -nubes_s3bucket.baza.vault_secrets["имя_ключа"] -nubes_s3bucket.baza.vault_url -nubes_s3bucket.baza.vault_user_path -nubes_s3bucket.baza.vault_fields -``` diff --git a/generated/test/docs/s3bucket_ops.md b/generated/test/docs/s3bucket_ops.md deleted file mode 100644 index 61b2abb..0000000 --- a/generated/test/docs/s3bucket_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](s3bucket_params_create.md) -- `delete` diff --git a/generated/test/docs/s3bucket_outputs.md b/generated/test/docs/s3bucket_outputs.md deleted file mode 100644 index f62a754..0000000 --- a/generated/test/docs/s3bucket_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["httpConnect"]` - diff --git a/generated/test/docs/s3bucket_params.md b/generated/test/docs/s3bucket_params.md deleted file mode 100644 index 9977e26..0000000 --- a/generated/test/docs/s3bucket_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Parameters - -- [Create params](s3bucket_params_create.md) -- [Modify params](s3bucket_params_modify.md) diff --git a/generated/test/docs/s3bucket_params_create.md b/generated/test/docs/s3bucket_params_create.md deleted file mode 100644 index 0ae6f44..0000000 --- a/generated/test/docs/s3bucket_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
124s3_user_uiduuidUID Корневой услуги S3. На основе него будет создан бакет.ref_svc_id=12
125bucket_namestringИмя бакета s3
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
126max_size-1Максимальный размер бакета s3. Если поставить 0, будет безлимит. Размер указывается в Bytes
127read_allbooleanfalseПубличный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета.value_list=false, true
128list_allbooleanfalseПубличный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете.value_list=false, true
129cors_allbooleanfalseПубличный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORSvalue_list=false, true
130placementstringHOTКласс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращенияvalue_list=HOT, COLD
diff --git a/generated/test/docs/s3bucket_params_modify.md b/generated/test/docs/s3bucket_params_modify.md deleted file mode 100644 index ca24765..0000000 --- a/generated/test/docs/s3bucket_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_s3bucket - -Service ID: `13` - -Service Name: S3 бакет - -[Manual](s3bucket.md) | [Create params](s3bucket_params_create.md) | [Modify params](s3bucket_params_modify.md) | [Output params](s3bucket_outputs.md) | [Operations](s3bucket_ops.md) | [Example](s3bucket_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/superset.md b/generated/test/docs/superset.md deleted file mode 100644 index 93094e9..0000000 --- a/generated/test/docs/superset.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## MAN - -
-Apache Superset как сервис.
Ресурсная платформа: k8s.
Автоматизация: k8s operator.
Авторизация: 2FA keycloak (для доменного логина @mgmt.nubes.ru) -
diff --git a/generated/test/docs/superset_example.md b/generated/test/docs/superset_example.md deleted file mode 100644 index 13aa0c4..0000000 --- a/generated/test/docs/superset_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Copy-ready manifest (`superset_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_superset" "baza" { - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - domain = "web01" # Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - emails = "testuser1" # Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - resource_cpu = 500 # Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - resource_memory = 512 # Квота памяти пода (Указывается в Megabytes) - resource_disk = 1 # Квота диска (Указывается в GIGAbytes) - resource_instances = 1 # Количество узлов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_superset.baza.state_params["имя_ключа"] -nubes_superset.baza.state_out["имя_ключа"] -nubes_superset.baza.state_params_flat["имя_ключа"] -nubes_superset.baza.state_out_flat["имя_ключа"] -nubes_superset.baza.vault_secrets["имя_ключа"] -nubes_superset.baza.vault_url -nubes_superset.baza.vault_user_path -nubes_superset.baza.vault_fields -``` diff --git a/generated/test/docs/superset_ops.md b/generated/test/docs/superset_ops.md deleted file mode 100644 index 5aa441d..0000000 --- a/generated/test/docs/superset_ops.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](superset_params_create.md) -- `delete` — DEV-Ветка удаления Superset diff --git a/generated/test/docs/superset_outputs.md b/generated/test/docs/superset_outputs.md deleted file mode 100644 index 4d7a1fd..0000000 --- a/generated/test/docs/superset_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/superset_params.md b/generated/test/docs/superset_params.md deleted file mode 100644 index 2984f1c..0000000 --- a/generated/test/docs/superset_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Parameters - -- [Create params](superset_params_create.md) -- [Modify params](superset_params_modify.md) diff --git a/generated/test/docs/superset_params_create.md b/generated/test/docs/superset_params_create.md deleted file mode 100644 index 6652cf1..0000000 --- a/generated/test/docs/superset_params_create.md +++ /dev/null @@ -1,29 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
109resource_realmstringНаименование кластера Kubernetes для подключенияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
14domainstringweb01Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealmregex=^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
20emailsstringtestuser1Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел
96resource_cpuinteger500Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядроminvalue=100; maxvalue=4000
97resource_memoryinteger512Квота памяти пода (Указывается в Megabytes)minvalue=128; maxvalue=8192
98resource_diskinteger1Квота диска (Указывается в GIGAbytes)minvalue=1; maxvalue=999
227resource_instancesinteger1Количество узловminvalue=1; maxvalue=7
diff --git a/generated/test/docs/superset_params_modify.md b/generated/test/docs/superset_params_modify.md deleted file mode 100644 index 5a6e1ca..0000000 --- a/generated/test/docs/superset_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_superset - -Service ID: `81` - -Service Name: Apache Superset - -[Manual](superset.md) | [Create params](superset_params_create.md) | [Modify params](superset_params_modify.md) | [Output params](superset_outputs.md) | [Operations](superset_ops.md) | [Example](superset_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/template.md b/generated/test/docs/template.md deleted file mode 100644 index b4d0dc3..0000000 --- a/generated/test/docs/template.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/template_example.md b/generated/test/docs/template_example.md deleted file mode 100644 index d2719b9..0000000 --- a/generated/test/docs/template_example.md +++ /dev/null @@ -1,45 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Copy-ready manifest (`template_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_template" "baza" { - cluster_configuration = "TODO" - startup_configuration = "TODO" - access_configuration = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_template.baza.state_params["имя_ключа"] -nubes_template.baza.state_out["имя_ключа"] -nubes_template.baza.state_params_flat["имя_ключа"] -nubes_template.baza.state_out_flat["имя_ключа"] -nubes_template.baza.vault_secrets["имя_ключа"] -nubes_template.baza.vault_url -nubes_template.baza.vault_user_path -nubes_template.baza.vault_fields -``` diff --git a/generated/test/docs/template_ops.md b/generated/test/docs/template_ops.md deleted file mode 100644 index f431055..0000000 --- a/generated/test/docs/template_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](template_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](template_params_modify.md) -- `reconcile` -- `resume` -- `suspend` diff --git a/generated/test/docs/template_outputs.md b/generated/test/docs/template_outputs.md deleted file mode 100644 index ab5623d..0000000 --- a/generated/test/docs/template_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/template_params.md b/generated/test/docs/template_params.md deleted file mode 100644 index 7fdd8d3..0000000 --- a/generated/test/docs/template_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Parameters - -- [Create params](template_params_create.md) -- [Modify params](template_params_modify.md) diff --git a/generated/test/docs/template_params_create.md b/generated/test/docs/template_params_create.md deleted file mode 100644 index 6266f53..0000000 --- a/generated/test/docs/template_params_create.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
813cluster_configurationmap-fixed
814startup_configurationmap-fixed
815access_configurationmap-fixed
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/template_params_modify.md b/generated/test/docs/template_params_modify.md deleted file mode 100644 index 4611040..0000000 --- a/generated/test/docs/template_params_modify.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_template - -Service ID: `2` - -Service Name: Темплейт k8s - -[Manual](template.md) | [Create params](template_params_create.md) | [Modify params](template_params_modify.md) | [Output params](template_outputs.md) | [Operations](template_ops.md) | [Example](template_example.md) - -## Modify params - - - - - - -
IDCodeTypeDescriptionConstraints
816cluster_configurationmap-fixed
817access_configurationmap-fixed
diff --git a/generated/test/docs/tenant.md b/generated/test/docs/tenant.md deleted file mode 100644 index 409820a..0000000 --- a/generated/test/docs/tenant.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/tenant_example.md b/generated/test/docs/tenant_example.md deleted file mode 100644 index 7e50ae6..0000000 --- a/generated/test/docs/tenant_example.md +++ /dev/null @@ -1,44 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Copy-ready manifest (`tenant_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_tenant" "baza" { - grafana_org_name = "TODO" # WZ-Код клиента - resource_realm = "TODO" # Платформа для развертывания -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_tenant.baza.state_params["имя_ключа"] -nubes_tenant.baza.state_out["имя_ключа"] -nubes_tenant.baza.state_params_flat["имя_ключа"] -nubes_tenant.baza.state_out_flat["имя_ключа"] -nubes_tenant.baza.vault_secrets["имя_ключа"] -nubes_tenant.baza.vault_url -nubes_tenant.baza.vault_user_path -nubes_tenant.baza.vault_fields -``` diff --git a/generated/test/docs/tenant_ops.md b/generated/test/docs/tenant_ops.md deleted file mode 100644 index 5058136..0000000 --- a/generated/test/docs/tenant_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](tenant_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](tenant_params_modify.md) diff --git a/generated/test/docs/tenant_outputs.md b/generated/test/docs/tenant_outputs.md deleted file mode 100644 index 4ebe277..0000000 --- a/generated/test/docs/tenant_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/tenant_params.md b/generated/test/docs/tenant_params.md deleted file mode 100644 index 4db7d6b..0000000 --- a/generated/test/docs/tenant_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Parameters - -- [Create params](tenant_params_create.md) -- [Modify params](tenant_params_modify.md) diff --git a/generated/test/docs/tenant_params_create.md b/generated/test/docs/tenant_params_create.md deleted file mode 100644 index 10d4d27..0000000 --- a/generated/test/docs/tenant_params_create.md +++ /dev/null @@ -1,21 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
239grafana_org_namestringWZ-Код клиентаregex=^WZ[\d]+$
240resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/test/docs/tenant_params_modify.md b/generated/test/docs/tenant_params_modify.md deleted file mode 100644 index cc3e107..0000000 --- a/generated/test/docs/tenant_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_tenant - -Service ID: `112` - -Service Name: Тенант в Grafana - -[Manual](tenant.md) | [Create params](tenant_params_create.md) | [Modify params](tenant_params_modify.md) | [Output params](tenant_outputs.md) | [Operations](tenant_ops.md) | [Example](tenant_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/valo_tenant.md b/generated/test/docs/valo_tenant.md deleted file mode 100644 index 6860e2f..0000000 --- a/generated/test/docs/valo_tenant.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## MAN - -
-# Инструкция по развертыванию Тенант Valo через платформу

## 1. Общая информация
Тенант Valo — логический изолированный экземпляр сервиса VALO Cloud, предоставляющий защищённое облачное хранилище, синхронизацию данных и доступ к документам с различных устройств. При создании тенант автоматически разворачивается в тестовом режиме сроком на 2 месяца. Перевод в промышленную эксплуатацию выполняется отдельной операцией.

### Доступные операции

* **create** — создание нового тенанта в тестовом режиме сроком на 2 месяца.
* **modify** — изменение настроек тенанта, включая перевод из ТЕСТ в ПРОД.
* **suspend** — выключение (приостановка работы) тенанта.
* **resume** — включение ранее приостановленного тенанта.
* **delete** — удаление тенанта; доступно только после выполнения операции suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создан тенант.
Пример значения: `valo.ngcloud.ru`.

### DNS-Префикс
Описание: Будет добавлено в зону valo.ngcloud.ru
Пример значения: `mysimpledomain`.

### Параметры хранилища
Описание: Сколько места будет выделено под использование в тенанте. Данные хранятся в S3. Размер указывается в Gigabytes
Пример значения: `10`.

### Настройки тенанта
Описание: Ряд конфигурации Valo-тенанта, такие как настройки пользователя и доступного функционала
Пример значения: `опционально в рамках настройки`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
Достаточно развернуть тенант в ТЕСТ. Срок предоставляется в 2 месяца. По истечению срока тенант автоматически переводится в `suspend` на стороне ресурсной платформы

### Промышленное окружение
Для разблокировки используйте операцию `modify`

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Статус тенанта
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация
Тенант всегда создаётся в режиме ТЕСТ и не может быть сразу переведён в ПРОД без операции modify.
Удаление тенанта возможно только после его выключения с помощью операции suspend.
Срок тестового режима составляет 2 месяца с момента создания.
Операции suspend и resume используются для временного управления доступностью сервиса без потери конфигурации.
-
diff --git a/generated/test/docs/valo_tenant_example.md b/generated/test/docs/valo_tenant_example.md deleted file mode 100644 index 0982a12..0000000 --- a/generated/test/docs/valo_tenant_example.md +++ /dev/null @@ -1,48 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Copy-ready manifest (`valo_tenant_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_valo_tenant" "baza" { - resource_realm = "TODO" - domain = "TODO" # Будет добавлено в зону valo.ngcloud.ru - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - valo_options = {} - s3_storage = 10 # Параметр указывается в `Gb` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_valo_tenant.baza.state_params["имя_ключа"] -nubes_valo_tenant.baza.state_out["имя_ключа"] -nubes_valo_tenant.baza.state_params_flat["имя_ключа"] -nubes_valo_tenant.baza.state_out_flat["имя_ключа"] -nubes_valo_tenant.baza.vault_secrets["имя_ключа"] -nubes_valo_tenant.baza.vault_url -nubes_valo_tenant.baza.vault_user_path -nubes_valo_tenant.baza.vault_fields -``` diff --git a/generated/test/docs/valo_tenant_ops.md b/generated/test/docs/valo_tenant_ops.md deleted file mode 100644 index 89cb168..0000000 --- a/generated/test/docs/valo_tenant_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](valo_tenant_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](valo_tenant_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/test/docs/valo_tenant_outputs.md b/generated/test/docs/valo_tenant_outputs.md deleted file mode 100644 index 2d4ea5d..0000000 --- a/generated/test/docs/valo_tenant_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/valo_tenant_params.md b/generated/test/docs/valo_tenant_params.md deleted file mode 100644 index 2c3d14f..0000000 --- a/generated/test/docs/valo_tenant_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Parameters - -- [Create params](valo_tenant_params_create.md) -- [Modify params](valo_tenant_params_modify.md) diff --git a/generated/test/docs/valo_tenant_params_create.md b/generated/test/docs/valo_tenant_params_create.md deleted file mode 100644 index a0e9538..0000000 --- a/generated/test/docs/valo_tenant_params_create.md +++ /dev/null @@ -1,38 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
655resource_realmstringfunc=getAvailableResourceRealms
656domainstringБудет добавлено в зону valo.ngcloud.ruregex=^[a-z0-9](?:[a-z0-9-]{3,61}[a-z0-9])?$; maxlength=61; minlength=3
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
657valo_optionsmap-fixed{}
658s3_storageinteger10Данные хранятся в отдельном экземпляре S3minvalue=1; maxvalue=999
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/valo_tenant_params_modify.md b/generated/test/docs/valo_tenant_params_modify.md deleted file mode 100644 index 4b07bec..0000000 --- a/generated/test/docs/valo_tenant_params_modify.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_valo_tenant - -Service ID: `149` - -Service Name: VALO Cloud - -[Manual](valo_tenant.md) | [Create params](valo_tenant_params_create.md) | [Modify params](valo_tenant_params_modify.md) | [Output params](valo_tenant_outputs.md) | [Operations](valo_tenant_ops.md) | [Example](valo_tenant_example.md) - -## Modify params - - - - - - -
IDCodeTypeDescriptionConstraints
659valo_optionsmap-fixed
660s3_storageintegerДанные хранятся в отдельном экземпляре S3
diff --git a/generated/test/docs/vapp.md b/generated/test/docs/vapp.md deleted file mode 100644 index 630f47c..0000000 --- a/generated/test/docs/vapp.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## MAN - -
-# Инструкция по развертыванию Виртуальный каталог ВМ (vApp) через платформу

## 1. Общая информация

**Виртуальный каталог ВМ (vApp)** — это логическая каталог, объединённая в единый управляемый объект. Сервис предназначен для совместного развертывания, управления жизненным циклом и сетевого взаимодействия набора связанных ВМ. Основные функции включают:
- централизованное управление включением, выключением и приостановкой группы ВМ;
- унифицированный сетевой доступ через привязанный Edge-шлюз;

### Доступные операции

**create** — Создание нового vApp с привязкой к заданным услугам VDC и Edge
**delete** — Удаление существующего vApp. Требуется предварительный перевод vApp в состояние *suspend*. Полное удаление возможно через 14 дней.
**suspend** — Остановка vApp (выключение всех ВМ внутри каталога)
**resume** — Запуск vApp (включение всех ВМ внутри каталога)

---

## 2. Параметры развертывания

Параметры берутся из операции **create**.

### UUID Услуги VDC
Уникальный идентификатор услуги «Виртуальный датацентр (vDC)».
Используется для определения вычислительной инфраструктуры, в которой будет развернут vApp.

### UUID Услуги Edge
Уникальный идентификатор услуги «Сетевой шлюз периметра (Edge)».
Обеспечивает маршрутизацию и сетевое подключение. Может быть привязан к группе VDC, поэтому выбирается отдельно.

### Имя vApp
Строгое имя, соответствующее маске формирования DNS-имени.
Используется как часть в DNS-имени при создании виртуальных машин.

---

## 3. Рекомендованные характеристики
Так как является промежуточным этапом для создания ВМ, все характеристики описываются в услуге `Виртуальная машина`

---

## 4. Выходные параметры

### Параметры vApp
Заданные при создании vApp

---

## 5. Дополнительная информация

- Привязка к VDC и Edge осуществляется раздельно, поскольку один Edge может обслуживать несколько VDC (через услугу `Группа виртуальных датацентров (groupvDC)`). Это гарантирует возможность развернуть ВМ в единой сети, но в разных виртуальных датацентрах.
- Перед удалением vApp необходимо вручную перевести его в состояние **suspend**. Удаление возможно только спустя 14 дней после этого шага.
- Операция delete удаляет весь vApp полностью, включая все виртуальные машины, связанные с ним.
- Рекомендуется заранее планировать сетевые связи и назначения DNS-имён для обеспечения корректной работы сервисов, развернутых внутри vApp.
- При проектировании инфраструктуры следует учитывать зависимости между Edge-шлюзом, VDC и размещаемыми ВМ, чтобы избежать ограничений при масштабировании и интеграции. -
diff --git a/generated/test/docs/vapp_example.md b/generated/test/docs/vapp_example.md deleted file mode 100644 index a8f08a7..0000000 --- a/generated/test/docs/vapp_example.md +++ /dev/null @@ -1,45 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Copy-ready manifest (`vapp_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vapp" "baza" { - nsxt_uid = "TODO" # UUID Услуги `Сетевой шлюз периметра (Edge)` - vapp_name = "TODO" # Уникальное в рамках организации - vdc_uid = "TODO" # UUID Услуги `Виртуальный датацентр (vDC)` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vapp.baza.state_params["имя_ключа"] -nubes_vapp.baza.state_out["имя_ключа"] -nubes_vapp.baza.state_params_flat["имя_ключа"] -nubes_vapp.baza.state_out_flat["имя_ключа"] -nubes_vapp.baza.vault_secrets["имя_ключа"] -nubes_vapp.baza.vault_url -nubes_vapp.baza.vault_user_path -nubes_vapp.baza.vault_fields -``` diff --git a/generated/test/docs/vapp_ops.md b/generated/test/docs/vapp_ops.md deleted file mode 100644 index b787780..0000000 --- a/generated/test/docs/vapp_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vapp_params_create.md) -- `delete` -- `reconcile` -- `resume` -- `suspend` diff --git a/generated/test/docs/vapp_outputs.md b/generated/test/docs/vapp_outputs.md deleted file mode 100644 index 0ff0f8e..0000000 --- a/generated/test/docs/vapp_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/vapp_params.md b/generated/test/docs/vapp_params.md deleted file mode 100644 index 4c7addc..0000000 --- a/generated/test/docs/vapp_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Parameters - -- [Create params](vapp_params_create.md) -- [Modify params](vapp_params_modify.md) diff --git a/generated/test/docs/vapp_params_create.md b/generated/test/docs/vapp_params_create.md deleted file mode 100644 index 3b23cff..0000000 --- a/generated/test/docs/vapp_params_create.md +++ /dev/null @@ -1,34 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
190nsxt_uiduuidК какой сети может быть подключен виртуальный каталогref_svc_id=22
191vapp_namestringИмеет строгую маску `^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$`

Используется в формировании DNS-Имени (для виртуальных машин)
regex=^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$; minlength=3
623vdc_uiduuidВ каких ресурсах будет создан виртуальный каталогref_svc_id=21
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/vapp_params_modify.md b/generated/test/docs/vapp_params_modify.md deleted file mode 100644 index 4fca747..0000000 --- a/generated/test/docs/vapp_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vapp - -Service ID: `26` - -Service Name: Виртуальный каталог ВМ (vApp) - -[Manual](vapp.md) | [Create params](vapp_params_create.md) | [Modify params](vapp_params_modify.md) | [Output params](vapp_outputs.md) | [Operations](vapp_ops.md) | [Example](vapp_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/vc_complex.md b/generated/test/docs/vc_complex.md deleted file mode 100644 index c83cece..0000000 --- a/generated/test/docs/vc_complex.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## MAN - -
-# Создает окружение для ВМ.

## Создает сервисы:
**Организация**
**Виртуальный датацентр**
**Каталог**
**Сетевой шлюз периметра**

-
diff --git a/generated/test/docs/vc_complex_example.md b/generated/test/docs/vc_complex_example.md deleted file mode 100644 index 5228d80..0000000 --- a/generated/test/docs/vc_complex_example.md +++ /dev/null @@ -1,59 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Copy-ready manifest (`vc_complex_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_complex" "baza" { - resource_realm = "TODO" # Платформа для развертывания - vapp_name = "TODO" # Имя vApp - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - vdc_provider_gateway = "sandbox-v1cl1-pvdc" # Взять из свойств ресурсной платформы. Путь .vcd.providerVdc - взять KEY providerGateway Cloud Director. Влияет ресурсы будут предоставлены. Является полем (List) в свойствах рес. платформы ЛК, но сам параметр передаётся только как один String - virtual_services_count = 1 # Кол-во виртуальных сервисов, которые выделяются на AVI. Во избежании коллапса пока выделяется до 4 - ip_space_name = "internet-ipv4-v1" # Имя ip Space для внешнего IP. Целесообразнее брать самый дешёвый, так как это vip для исходящего трафика. Необходимо задавать если включен needExternalAddressSNAT - storage_config = [{"name": "", "size": 1024}] # Описывается как массив объектов, где описывается имя политики и её размер - vdc_network_pool = "nsxt-sandbox-geneve-np" - cpu_guaranteed = 20 - mem_guaranteed = 20 - segroup_name = "SEGROUP-SANDBOX-CL1-SHARED-01" # Наименование segroup, в котором будут выделяться пулы на AVI - need_external_address_snat = true # Выделяет внешний IP на Edge. Используется для SNAT всего трафика - need_enable_avi = false # Включает AVI в Cloud Director - cpu_allocated = 1 # шт - mem_allocated = 10 # gb - v_ipcount = 0 # ш -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_complex.baza.state_params["имя_ключа"] -nubes_vc_complex.baza.state_out["имя_ключа"] -nubes_vc_complex.baza.state_params_flat["имя_ключа"] -nubes_vc_complex.baza.state_out_flat["имя_ключа"] -nubes_vc_complex.baza.vault_secrets["имя_ключа"] -nubes_vc_complex.baza.vault_url -nubes_vc_complex.baza.vault_user_path -nubes_vc_complex.baza.vault_fields -``` diff --git a/generated/test/docs/vc_complex_ops.md b/generated/test/docs/vc_complex_ops.md deleted file mode 100644 index 9d016bc..0000000 --- a/generated/test/docs/vc_complex_ops.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_complex_params_create.md) diff --git a/generated/test/docs/vc_complex_outputs.md b/generated/test/docs/vc_complex_outputs.md deleted file mode 100644 index 629a059..0000000 --- a/generated/test/docs/vc_complex_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/vc_complex_params.md b/generated/test/docs/vc_complex_params.md deleted file mode 100644 index 82b3c13..0000000 --- a/generated/test/docs/vc_complex_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Parameters - -- [Create params](vc_complex_params_create.md) -- [Modify params](vc_complex_params_modify.md) diff --git a/generated/test/docs/vc_complex_params_create.md b/generated/test/docs/vc_complex_params_create.md deleted file mode 100644 index 6b0b9ec..0000000 --- a/generated/test/docs/vc_complex_params_create.md +++ /dev/null @@ -1,37 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
332resource_realmstringНаименование ресурсной платформыfunc=getAvailableResourceRealms
334vapp_namestringИмя vAppregex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
358vdc_provider_gatewaystringsandbox-v1cl1-pvdcВзять из свойств ресурсной платформы.
Путь .vcd.providerVdc - взять KEY

providerGateway Cloud Director. Влияет ресурсы будут предоставлены. Является полем (List&lt;String&gt;) в свойствах рес. платформы ЛК, но сам параметр передаётся только как один String
359virtual_services_count1Кол-во виртуальных сервисов, которые выделяются на AVI. Во избежании коллапса пока выделяется до 4minvalue=1; maxvalue=4
360ip_space_namestringinternet-ipv4-v1Имя ip Space для внешнего IP. Целесообразнее брать самый дешёвый, так как это vip для исходящего трафика. Необходимо задавать если включен needExternalAddressSNAT
399storage_configjson[{"name": "", "size": 1024}]Описывается как массив объектов, где описывается имя политики и её размер
400vdc_network_poolstringnsxt-sandbox-geneve-np
401cpu_guaranteedinteger20value_list=20, 50, 80
402mem_guaranteedinteger20value_list=20, 50, 80
403segroup_namestringSEGROUP-SANDBOX-CL1-SHARED-01Наименование segroup, в котором будут выделяться пулы на AVI
404need_external_address_snatbooleantrueВыделяет внешний IP на Edge. Используется для SNAT всего трафикаvalue_list=false, true
405need_enable_avibooleanfalseВключает AVI в Cloud Directorvalue_list=false, true
566cpu_allocatedstring1штminvalue=1
567mem_allocatedinteger10gbminvalue=1
568v_ipcountinteger0шminvalue=0; maxvalue=20
diff --git a/generated/test/docs/vc_complex_params_modify.md b/generated/test/docs/vc_complex_params_modify.md deleted file mode 100644 index b6a1be3..0000000 --- a/generated/test/docs/vc_complex_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_complex - -Service ID: `113` - -Service Name: Быстрый старт - -[Manual](vc_complex.md) | [Create params](vc_complex_params_create.md) | [Modify params](vc_complex_params_modify.md) | [Output params](vc_complex_outputs.md) | [Operations](vc_complex_ops.md) | [Example](vc_complex_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/vc_nsxt.md b/generated/test/docs/vc_nsxt.md deleted file mode 100644 index 0c8056d..0000000 --- a/generated/test/docs/vc_nsxt.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## MAN - -
-# Инструкция по развертыванию Сетевой шлюз периметра (Edge) через платформу

## 1. Общая информация

Сервис **Сетевой шлюз периметра (Edge)** предназначен для создания периметрового сетевого шлюза в рамках одного виртуального датацентра (vDC) или группы виртуальных датацентров (groupvDC).
При создании автоматически разворачивается routed-сеть с адресным пространством `10.10.102.0/24`.
Сервис обеспечивает сетевую изоляцию, маршрутизацию, а также может включать функциональность балансировщика нагрузки AVI (ALB) для последующей интеграции, включая поддержку кластеров Штурвал.

### Доступные операции

**create** — Создание нового Edge с привязкой к vDC или groupvDC и развёртыванием routed-сети.
**delete** — Удаление ранее созданного Edge. Недоступно при наличии зависимых услуг (vApp, VM, Кластер Штурвал).
**modify** — Изменение параметров и сетевых настроек существующего Edge.

---

## 2. Параметры развертывания

Ниже приведены параметры операции **create**.

### Тип родительской услуги
Определяет контекст размещения Edge.
Допустимые значения: `vdc`, `groupvdc`.
Использование:
- При выборе `vdc` обязателен параметр **UUID VDC**.
- При выборе `groupvdc` обязателен параметр **UUID Группы VDC**.

### UUID VDC
Идентификатор виртуального датацентра.
Необходимо предварительно создать vDC через услугу «Виртуальный датацентр (vDC)».
Указывается только при выборе родительского типа `vdc`.

### UUID Группы VDC
Идентификатор группы виртуальных датацентров.
Создаётся через услугу «Группа виртуальных датацентров (groupvDC)».
Используется при выборе родительского типа `groupvdc`.

### Включить ALB
Флаг активации AVI Load Balancer в Cloud Director.
Пример значения: `true`/`false`.
Нужен для развёртывания кластера Штурвал и возможности создания Virtual Services.

### Наименование segroup
Имя сервиса групп (segroup) на уровне ресурсной платформы.
Обязательно при включённом ALB.
Определяет группу, в которой будут выделяться пулы AVI для Virtual Services.

### virtualServicesCount
Количество резервируемых виртуальных сервисов (Virtual Services) на AVI.
Типичное значение: 1–10 в зависимости от нагрузки.

---

## 3. Рекомендованные характеристики

### Тестовое окружение (Test)

- Тип родительской услуги: `vdc`
- virtualServicesCount: 1–2
- ALB: выключен по умолчанию (включать только при необходимости тестирования Штурвала)
- segroup: задаётся только при включённом ALB
- VDC гарантии CPU/RAM: минимальные (поскольку изменить их после создания нельзя)

### Промышленное окружение (Production)

- Тип родительской услуги: `groupvdc` при работе с распределёнными нагрузками или `vdc` для локализованных проектов
- virtualServicesCount: 3–10, исходя из предполагаемого количества публикаций
- ALB: включён, если требуется высокая доступность сервисов или используется кластер Штурвал
- segroup: рекомендуется использовать выделенную группу под проект
- VDC гарантии CPU/RAM: повышенные, с учётом того, что изменить их после создания невозможно без пересоздания vDC

---

## 4. Выходные параметры

### Имя Edge
Уникальное название созданного сетевого шлюза, используется для ссылок и дальнейших операций.

### Имя routed-сети
Автоматически созданная routed-сеть с подсетью `10.10.102.0/24`, используется для подключения ресурсов.

### Параметры Edge
Набор параметров, указанных пользователем при создании: тип услуги, ALB, segroup, virtualServicesCount и др.
Используются в операциях modify и для анализа состояния сервиса.

---

## 5. Дополнительная информация

- В рамках сервиса **один раз при создании задаётся гарантированная доля CPU/RAM vDC**. Изменить её невозможно — требуется пересоздание vDC.
- Удаление Edge недоступно при наличии зависимых ресурсов (vApp, VM, кластер Штурвал).
- При использовании ALB необходимо корректно указывать segroup, чтобы обеспечить корректное выделение пулов AVI.
- При выборе режима `groupvdc` следует учитывать распределение нагрузки между несколькими vDC.
- SNAT для всех ресурсов внутри Edge можно активировать через операцию modify (параметры выделения VIP и ipSpace).

-
diff --git a/generated/test/docs/vc_nsxt_example.md b/generated/test/docs/vc_nsxt_example.md deleted file mode 100644 index 1ca1eb2..0000000 --- a/generated/test/docs/vc_nsxt_example.md +++ /dev/null @@ -1,47 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Copy-ready manifest (`vc_nsxt_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_nsxt" "baza" { - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - need_enable_avi = false # Включение Load Balancer - virtual_services_count = 1 # Кол-во виртуальных сервисов, которые **резервируются** на AVI - vdc_type = "vdc" # Тип родительской услуги -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_nsxt.baza.state_params["имя_ключа"] -nubes_vc_nsxt.baza.state_out["имя_ключа"] -nubes_vc_nsxt.baza.state_params_flat["имя_ключа"] -nubes_vc_nsxt.baza.state_out_flat["имя_ключа"] -nubes_vc_nsxt.baza.vault_secrets["имя_ключа"] -nubes_vc_nsxt.baza.vault_url -nubes_vc_nsxt.baza.vault_user_path -nubes_vc_nsxt.baza.vault_fields -``` diff --git a/generated/test/docs/vc_nsxt_ops.md b/generated/test/docs/vc_nsxt_ops.md deleted file mode 100644 index 03af84f..0000000 --- a/generated/test/docs/vc_nsxt_ops.md +++ /dev/null @@ -1,14 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_nsxt_params_create.md) -- `delete` — Невозможно удалить если routed-сеть в Edge связана с: - vApp - VM - Kubernetes-кластер Штурвал Запустить операцию возможно, но будет ошибка -- `modify` — Изменение кластера. Параметры: [Modify params](vc_nsxt_params_modify.md) -- `reconcile` diff --git a/generated/test/docs/vc_nsxt_outputs.md b/generated/test/docs/vc_nsxt_outputs.md deleted file mode 100644 index 717cbc4..0000000 --- a/generated/test/docs/vc_nsxt_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/vc_nsxt_params.md b/generated/test/docs/vc_nsxt_params.md deleted file mode 100644 index 2cf1cc1..0000000 --- a/generated/test/docs/vc_nsxt_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Parameters - -- [Create params](vc_nsxt_params_create.md) -- [Modify params](vc_nsxt_params_modify.md) diff --git a/generated/test/docs/vc_nsxt_params_create.md b/generated/test/docs/vc_nsxt_params_create.md deleted file mode 100644 index 90c487e..0000000 --- a/generated/test/docs/vc_nsxt_params_create.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
8vdc_uidstringНеобходимо, если выбран тип подключаемой VDC: `vdc`ref_svc_id=21
622vdc_group_uidstringНеобходимо, если выбран тип подключаемой VDC: `groupvdc`ref_svc_id=29
825qos_profileif (vdcUid != '&quot;) {
наборфункций1
}

elif (vdcGroupUid != &quot;&quot;) {
наборфункций2
}

else {
return &quot;Необходимо выбрать vdc или vdcgroup&quot;
}
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
340need_enable_avibooleanfalseПараметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указатьvalue_list=false, true
341virtual_services_countinteger1Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB`
minvalue=1; maxvalue=4
621vdc_typestringvdcПри выборе vdc обеспечивает сетевую доступность только в рамках этого vdc
При выборе groupvdc обеспечивает сетевую доступность между всеми vdc, которые включены в groupvdc
value_list=vdc, vdcGroup
diff --git a/generated/test/docs/vc_nsxt_params_modify.md b/generated/test/docs/vc_nsxt_params_modify.md deleted file mode 100644 index 0030cd9..0000000 --- a/generated/test/docs/vc_nsxt_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_nsxt - -Service ID: `22` - -Service Name: Сетевой шлюз периметра (Edge) - -[Manual](vc_nsxt.md) | [Create params](vc_nsxt_params_create.md) | [Modify params](vc_nsxt_params_modify.md) | [Output params](vc_nsxt_outputs.md) | [Operations](vc_nsxt_ops.md) | [Example](vc_nsxt_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
368need_enable_avibooleanПараметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указатьvalue_list=false, true
369virtual_services_countintegerВо избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB`
minvalue=1; maxvalue=4
372ip_space_namestringНеобходимо указывать, если включён параметр `Выделить VIP для SNAT`
856qos_profilestring
diff --git a/generated/test/docs/vc_org.md b/generated/test/docs/vc_org.md deleted file mode 100644 index e500201..0000000 --- a/generated/test/docs/vc_org.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## MAN - -
-# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Url организации
Для быстрого доступа в тенант

### Статус организации
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)** привязанный к этой организации;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к vdc выше.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak. -
diff --git a/generated/test/docs/vc_org_example.md b/generated/test/docs/vc_org_example.md deleted file mode 100644 index 5bae91c..0000000 --- a/generated/test/docs/vc_org_example.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Copy-ready manifest (`vc_org_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_org" "baza" { - resource_realm = "TODO" # Облако в котором будет развёрнут тенант - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - organization_type = "iaas" # Доступ к организации предоставляется только при выборе `iaas` -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_org.baza.state_params["имя_ключа"] -nubes_vc_org.baza.state_out["имя_ключа"] -nubes_vc_org.baza.state_params_flat["имя_ключа"] -nubes_vc_org.baza.state_out_flat["имя_ключа"] -nubes_vc_org.baza.vault_secrets["имя_ключа"] -nubes_vc_org.baza.vault_url -nubes_vc_org.baza.vault_user_path -nubes_vc_org.baza.vault_fields -``` diff --git a/generated/test/docs/vc_org_ops.md b/generated/test/docs/vc_org_ops.md deleted file mode 100644 index aebdbcb..0000000 --- a/generated/test/docs/vc_org_ops.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_org_params_create.md) -- `create_user` — . См. [nubes_vc_org_user](vc_org_user.md) -- `delete` — Удалить возможно только через 14 дней после выполнения операции `suspend` **ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого тенанта** Если существуют инстансы VDC, Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов -- `delete_user` — . См. [nubes_vc_org_user](vc_org_user.md) -- `modify` — Изменение кластера. Параметры: [Modify params](vc_org_params_modify.md) -- `reconcile` -- `resume` -- `suspend` — Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри тенанта diff --git a/generated/test/docs/vc_org_outputs.md b/generated/test/docs/vc_org_outputs.md deleted file mode 100644 index 9de11b9..0000000 --- a/generated/test/docs/vc_org_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["urlConnect"]` - diff --git a/generated/test/docs/vc_org_params.md b/generated/test/docs/vc_org_params.md deleted file mode 100644 index e187b07..0000000 --- a/generated/test/docs/vc_org_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Parameters - -- [Create params](vc_org_params_create.md) -- [Modify params](vc_org_params_modify.md) diff --git a/generated/test/docs/vc_org_params_create.md b/generated/test/docs/vc_org_params_create.md deleted file mode 100644 index 28f12f0..0000000 --- a/generated/test/docs/vc_org_params_create.md +++ /dev/null @@ -1,36 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
418resource_realmstringВыбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы
func=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
556organization_typestringiaasДоступ к организации предоставляется только при выборе `iaas`value_list=iaas, saas
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/vc_org_params_modify.md b/generated/test/docs/vc_org_params_modify.md deleted file mode 100644 index 4142f72..0000000 --- a/generated/test/docs/vc_org_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_org - -Service ID: `19` - -Service Name: Организация в Cloud Director - -[Manual](vc_org.md) | [Create params](vc_org_params_create.md) | [Modify params](vc_org_params_modify.md) | [Output params](vc_org_outputs.md) | [Operations](vc_org_ops.md) | [Example](vc_org_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
662v_ipconfigurearray-map-fixed
diff --git a/generated/test/docs/vc_org_saas.md b/generated/test/docs/vc_org_saas.md deleted file mode 100644 index 95ae27c..0000000 --- a/generated/test/docs/vc_org_saas.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## MAN - -
-Верхнеуровневая сущность создаваемая для Заказчика.
Внутри Организация вы можете создать: Виртуальные датацентры, Каталоги. -
diff --git a/generated/test/docs/vc_org_saas_example.md b/generated/test/docs/vc_org_saas_example.md deleted file mode 100644 index c460211..0000000 --- a/generated/test/docs/vc_org_saas_example.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Copy-ready manifest (`vc_org_saas_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_org_saas" "baza" { - resource_realm = "TODO" # Платформа для развертывания -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_org_saas.baza.state_params["имя_ключа"] -nubes_vc_org_saas.baza.state_out["имя_ключа"] -nubes_vc_org_saas.baza.state_params_flat["имя_ключа"] -nubes_vc_org_saas.baza.state_out_flat["имя_ключа"] -nubes_vc_org_saas.baza.vault_secrets["имя_ключа"] -nubes_vc_org_saas.baza.vault_url -nubes_vc_org_saas.baza.vault_user_path -nubes_vc_org_saas.baza.vault_fields -``` diff --git a/generated/test/docs/vc_org_saas_ops.md b/generated/test/docs/vc_org_saas_ops.md deleted file mode 100644 index bcc4618..0000000 --- a/generated/test/docs/vc_org_saas_ops.md +++ /dev/null @@ -1,14 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_org_saas_params_create.md) -- `delete` -- `resume` -- `suspend` diff --git a/generated/test/docs/vc_org_saas_outputs.md b/generated/test/docs/vc_org_saas_outputs.md deleted file mode 100644 index 15052c9..0000000 --- a/generated/test/docs/vc_org_saas_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/vc_org_saas_params.md b/generated/test/docs/vc_org_saas_params.md deleted file mode 100644 index a9c08f3..0000000 --- a/generated/test/docs/vc_org_saas_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Parameters - -- [Create params](vc_org_saas_params_create.md) -- [Modify params](vc_org_saas_params_modify.md) diff --git a/generated/test/docs/vc_org_saas_params_create.md b/generated/test/docs/vc_org_saas_params_create.md deleted file mode 100644 index d73866d..0000000 --- a/generated/test/docs/vc_org_saas_params_create.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
185resource_realmstringНаименование ресурсной платформыfunc=getAvailableResourceRealms
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. - -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/vc_org_saas_params_modify.md b/generated/test/docs/vc_org_saas_params_modify.md deleted file mode 100644 index ad45c99..0000000 --- a/generated/test/docs/vc_org_saas_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_org_saas - -Service ID: `20` - -Service Name: Организация [DEPRECATED] - -[Manual](vc_org_saas.md) | [Create params](vc_org_saas_params_create.md) | [Modify params](vc_org_saas_params_modify.md) | [Output params](vc_org_saas_outputs.md) | [Operations](vc_org_saas_ops.md) | [Example](vc_org_saas_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/vc_org_user.md b/generated/test/docs/vc_org_user.md deleted file mode 100644 index 10b4e0f..0000000 --- a/generated/test/docs/vc_org_user.md +++ /dev/null @@ -1,27 +0,0 @@ -# Resource nubes_vc_org_user - -Service: `nubes_vc_org` (ID: 19) - -[Организация в Cloud Director (основной)](vc_org.md) | [Operations](vc_org_ops.md) | [User](vc_org_user.md) | [Example](vc_org_user_example.md) - -## Create params - -**Обязательные параметры** - -None. - -**Параметры со значением по умолчанию** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
871adminsarray-map-fixed[{}]
- -## Delete params - - - - - -
IDCodeTypeDescriptionConstraints
872adminsarray-map-fixed
diff --git a/generated/test/docs/vc_org_user_example.md b/generated/test/docs/vc_org_user_example.md deleted file mode 100644 index 6acd8bd..0000000 --- a/generated/test/docs/vc_org_user_example.md +++ /dev/null @@ -1,33 +0,0 @@ -# Resource nubes_vc_org_user — Example - -Service: `nubes_vc_org` (ID: 19) - -[Организация в Cloud Director (основной)](vc_org.md) | [Operations](vc_org_ops.md) | [User](vc_org_user.md) | [Example](vc_org_user_example.md) - -## Copy-ready manifest (`vc_org_user_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_vc_org должен быть создан заранее -# resource "nubes_vc_org" "baza" { ... } - -resource "nubes_vc_org_user" "example" { - vc_org_id = nubes_vc_org.baza.id - - # Параметры со значением по умолчанию - admins = [{}] -} -``` diff --git a/generated/test/docs/vc_vdc.md b/generated/test/docs/vc_vdc.md deleted file mode 100644 index 2d8fa57..0000000 --- a/generated/test/docs/vc_vdc.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## MAN - -
-# Инструкция по развертыванию Виртуальный датацентр (vDC) через платформу

## 1. Общая информация

**Виртуальный датацентр (vDC)** — это логическая изолированная среда в VMware Cloud Director, предназначенная для размещения и управления виртуальными машинами, сетевой инфраструктурой и ресурсами хранения. Сервис обеспечивает выделение вычислительных ресурсов под конкретную организацию и предоставляет гибкие параметры масштабирования, контроля потребления и разделения ресурсов.

### Доступные операции

**create** — Создание виртуального датацентра (vDC) с заданными параметрами CPU, RAM, Storage и сетевой конфигурацией.
**delete** — Удаление vDC. Требуется предварительный перевод vDC в состояние *suspend*. Полное удаление возможно через 14 дней.
**modify** — Внесение изменений в параметры ресурсов (CPU/RAM/Storage), выделенных для vDC.
**suspend** — Заморозка vDC. Новые ресурсы или изменения внутри vDC становятся невозможными, работа ВМ не останавливается.
**resume** — Разморозка vDC. Восстановление возможности управления сущностями внутри vDC.

---

## 2. Параметры развертывания

Ниже перечислены входные параметры операции **create**.

### UUID Организации
Уникальный идентификатор организации в Cloud Director. Перед созданием vDC требуется предварительное создание услугу `Организация в Cloud Director`.

### Provider VDC в Cloud Director
Свойство ресурсной платформы, определяющее, какой пул физических ресурсов будет использоваться.

### Network Pool в Cloud Director
Определяет возможности сетевой конфигурации, включая создание Edge Gateway и выход во внешние сети.

### Гарантированная доля ЯДЕР
Гарантированный процент вычислительных ресурсов (CPU), закрепленный за vDC. Значение устанавливается разово при создании.

### Гарантированная доля ОЗУ
Гарантированный процент оперативной памяти, закрепленный за vDC. Также задаётся один раз при создании.

### Сколько аллоцировать на VDC ЯДЕР
Количество виртуальных ядер, выделяемых в рамках vDC.

### Сколько аллоцировать на VDC ОЗУ
Количество оперативной памяти в GB, выделяемой для vDC.

### Конфигурация Storage
Набор дисковых политик и их объёмов, выделяемых для vDC. Указывается имя политики и требуемый размер (GB).

---

## 3. Рекомендованные характеристики

### Тестовое окружение

- Количество ядер CPU: 10–20
- Аллоцируемая RAM: 16–64 GB
- Гарантированная доля CPU: 20%
- Гарантированная доля RAM: 20%
- Storage:
- Политика `SATA`
- Объём: 100–300 GB

### Промышленное окружение

- Количество ядер CPU: 16–128
- Аллоцируемая RAM: 64–512 GB
- Гарантированная доля CPU: 50%
- Гарантированная доля RAM: 50%
- Storage:
- Политики уровня `SSD`
- Объём: 1–10 TB, выбор несколько политик под разные нагрузки

---

## 4. Выходные параметры

Выходные параметры формируются операцией **create** (и используются другими операциями):

### Имя vDC
Уникальный идентификатор созданного виртуального датацентра. Используется в дальнейших операциях (modify, suspend, delete).

### Параметры выделенных ресурсов
Подтверждение итогового объёма CPU/RAM/Storage, выделенных vDC. Используются для учёта и контроля потребления.

---

## 5. Дополнительная информация

- Перед созданием vDC необходимо обеспечить наличие корректно созданной организации и доступных пула ресурсов ресурсной платформы.
- Гарантированная доля CPU и RAM задаётся **однократно при создании vDC**. После развертывания изменить эти значения невозможно; для изменения необходимо пересоздать vDC.
- Удаление vDC возможно только через **14 дней после перевода в состояние *suspend***. Удаление очищает все связанные сущности (ВМ, сети, каталоги), поэтому необходимо убедиться, что данные перенесены.
- Платформа Cloud Director использует концепцию изолированных организационных ресурсов, поэтому корректная настройка Provider VDC и Network Pool является обязательной при создании vDC.
- При изменении параметров (modify) изменяются только показатели CPU, RAM и Storage. Сетевые параметры и гарантированные доли остаются неизменными.
-
diff --git a/generated/test/docs/vc_vdc_example.md b/generated/test/docs/vc_vdc_example.md deleted file mode 100644 index 5eaf99a..0000000 --- a/generated/test/docs/vc_vdc_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Copy-ready manifest (`vc_vdc_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_vdc" "baza" { - organization_uid = "TODO" # Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` - provider_vdc = "TODO" # Приписка `2.8` - Скорость vCPU - 2800MHz И так далее... - network_provider = "TODO" - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - storage_config = [{}] # Первая политика в списке указывается как "По умолчанию" - cpu_guaranteed = 20 # % резервирования - cpu_allocated = 80 # шт - mem_allocated = 200 # gb -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vdc.baza.state_params["имя_ключа"] -nubes_vc_vdc.baza.state_out["имя_ключа"] -nubes_vc_vdc.baza.state_params_flat["имя_ключа"] -nubes_vc_vdc.baza.state_out_flat["имя_ключа"] -nubes_vc_vdc.baza.vault_secrets["имя_ключа"] -nubes_vc_vdc.baza.vault_url -nubes_vc_vdc.baza.vault_user_path -nubes_vc_vdc.baza.vault_fields -``` diff --git a/generated/test/docs/vc_vdc_group.md b/generated/test/docs/vc_vdc_group.md deleted file mode 100644 index 1ff3cd6..0000000 --- a/generated/test/docs/vc_vdc_group.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## MAN - -
-# Инструкция по развертыванию Группа виртуальных датацентров (groupvDC) через платформу

## 1. Общая информация

Сервис **Группа виртуальных датацентров (groupvDC)** предназначен для логического объединения нескольких виртуальных датацентров (vDC) в единую группу. Это позволяет растягивать SDN между разными vDC и централизованно управлять сетевой связностью. Управление инфраструктурой осуществляется через Cloud Director.
Сервис применяется в случаях, когда требуется обеспечить единое сетевое пространство для распределенных виртуальных датацентров.

### Доступные операции

**create** — Создание новой группы виртуальных датацентров.
**delete** — Удаление существующей группы vDC.
**add_vdc** — Добавление дополнительного виртуального датацентра в группу.
**remove_vdc** — Удаление ранее добавленного виртуального датацентра из группы.

---

## 2. Параметры развертывания

Параметры операции **create**:

### UUID VDC
Идентификатор виртуального датацентра, который будет являться первичным в группе.
Описание: требуется предварительно создать виртуальный датацентр с помощью услуги `Виртуальный датацентр (vDC)`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Для тестового окружения создавать группу VDC нет необходимости, так как это создаёт дополнительный слой абстракции в Cloud Director

### Промышленное окружение
- Для промышленного окружения, если в тенанте существуют разные VDC, создание groupvdc позволит снизить сетевые издержки (за счёт общей сети)

---

## 4. Выходные параметры

### Параметры groupvdc
Набор параметров, указанных пользователем при создании

---

## 5. Дополнительная информация
- Группа vDC используется для растягивания SDN между несколькими виртуальными датацентрами. Управление всеми сетевыми элементами внутри группы выполняется Cloud Director.
- Удалить первичный vDC (тот, что был указан при операции **create**) невозможно. Для его удаления необходимо удалить всю группу и создать новую.
- Перед добавлением любого vDC в группу он должен быть предварительно развернут через сервис `Виртуальный датацентр (vDC)`.
- Сети создаются не в этой услуге, а в услуге `Сетевой шлюз периметра (Edge)`. В ней необходимо будет выбрать тип `groupvdc` -
diff --git a/generated/test/docs/vc_vdc_group_example.md b/generated/test/docs/vc_vdc_group_example.md deleted file mode 100644 index a60fbff..0000000 --- a/generated/test/docs/vc_vdc_group_example.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Copy-ready manifest (`vc_vdc_group_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_vdc_group" "baza" { - vdc_uid = "TODO" -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vdc_group.baza.state_params["имя_ключа"] -nubes_vc_vdc_group.baza.state_out["имя_ключа"] -nubes_vc_vdc_group.baza.state_params_flat["имя_ключа"] -nubes_vc_vdc_group.baza.state_out_flat["имя_ключа"] -nubes_vc_vdc_group.baza.vault_secrets["имя_ключа"] -nubes_vc_vdc_group.baza.vault_url -nubes_vc_vdc_group.baza.vault_user_path -nubes_vc_vdc_group.baza.vault_fields -``` diff --git a/generated/test/docs/vc_vdc_group_ops.md b/generated/test/docs/vc_vdc_group_ops.md deleted file mode 100644 index ed3ebe7..0000000 --- a/generated/test/docs/vc_vdc_group_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Operations - -- `add_vdc` — **Не нужно** выбирать UUID VDC, который уже был добавлен в группу. См. [nubes_vc_vdc_group_vdc](vc_vdc_group_vdc.md) -- `create` — Создание кластера. Параметры: [Create params](vc_vdc_group_params_create.md) -- `delete` -- `reconcile` -- `remove_vdc` — . См. [nubes_vc_vdc_group_vdc](vc_vdc_group_vdc.md) diff --git a/generated/test/docs/vc_vdc_group_outputs.md b/generated/test/docs/vc_vdc_group_outputs.md deleted file mode 100644 index 5714cde..0000000 --- a/generated/test/docs/vc_vdc_group_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/vc_vdc_group_params.md b/generated/test/docs/vc_vdc_group_params.md deleted file mode 100644 index d292ab9..0000000 --- a/generated/test/docs/vc_vdc_group_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Parameters - -- [Create params](vc_vdc_group_params_create.md) -- [Modify params](vc_vdc_group_params_modify.md) diff --git a/generated/test/docs/vc_vdc_group_params_create.md b/generated/test/docs/vc_vdc_group_params_create.md deleted file mode 100644 index 624e982..0000000 --- a/generated/test/docs/vc_vdc_group_params_create.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - -
IDCodeTypeDescriptionConstraints
618vdc_uiduuidref_svc_id=21
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/test/docs/vc_vdc_group_params_modify.md b/generated/test/docs/vc_vdc_group_params_modify.md deleted file mode 100644 index 721de57..0000000 --- a/generated/test/docs/vc_vdc_group_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vc_vdc_group - -Service ID: `29` - -Service Name: Группа датацентров - -[Manual](vc_vdc_group.md) | [Create params](vc_vdc_group_params_create.md) | [Modify params](vc_vdc_group_params_modify.md) | [Output params](vc_vdc_group_outputs.md) | [Operations](vc_vdc_group_ops.md) | [Example](vc_vdc_group_example.md) - -## Modify params - -None. diff --git a/generated/test/docs/vc_vdc_group_vdc.md b/generated/test/docs/vc_vdc_group_vdc.md deleted file mode 100644 index 0bf40c0..0000000 --- a/generated/test/docs/vc_vdc_group_vdc.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vdc_group_vdc - -Service: `nubes_vc_vdc_group` (ID: 29) - -[Группа датацентров (основной)](vc_vdc_group.md) | [Operations](vc_vdc_group_ops.md) | [Vdc](vc_vdc_group_vdc.md) | [Example](vc_vdc_group_vdc_example.md) - -## Create params - -None. - -## Delete params - -None. diff --git a/generated/test/docs/vc_vdc_group_vdc_example.md b/generated/test/docs/vc_vdc_group_vdc_example.md deleted file mode 100644 index 83b0d9e..0000000 --- a/generated/test/docs/vc_vdc_group_vdc_example.md +++ /dev/null @@ -1,30 +0,0 @@ -# Resource nubes_vc_vdc_group_vdc — Example - -Service: `nubes_vc_vdc_group` (ID: 29) - -[Группа датацентров (основной)](vc_vdc_group.md) | [Operations](vc_vdc_group_ops.md) | [Vdc](vc_vdc_group_vdc.md) | [Example](vc_vdc_group_vdc_example.md) - -## Copy-ready manifest (`vc_vdc_group_vdc_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} - -# Родительский ресурс — nubes_vc_vdc_group должен быть создан заранее -# resource "nubes_vc_vdc_group" "baza" { ... } - -resource "nubes_vc_vdc_group_vdc" "example" { - vc_vdc_group_id = nubes_vc_vdc_group.baza.id -} -``` diff --git a/generated/test/docs/vc_vdc_ops.md b/generated/test/docs/vc_vdc_ops.md deleted file mode 100644 index b1a1776..0000000 --- a/generated/test/docs/vc_vdc_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vdc_params_create.md) -- `delete` — Удалить возможно только через 14 дней после выполнения операции `suspend` **ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого VDC** Если существуют инстансы Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vdc_params_modify.md) -- `reconcile` -- `resume` -- `suspend` — Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри VDC diff --git a/generated/test/docs/vc_vdc_outputs.md b/generated/test/docs/vc_vdc_outputs.md deleted file mode 100644 index a435292..0000000 --- a/generated/test/docs/vc_vdc_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["vdcName"]` - diff --git a/generated/test/docs/vc_vdc_params.md b/generated/test/docs/vc_vdc_params.md deleted file mode 100644 index 03c0037..0000000 --- a/generated/test/docs/vc_vdc_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Parameters - -- [Create params](vc_vdc_params_create.md) -- [Modify params](vc_vdc_params_modify.md) diff --git a/generated/test/docs/vc_vdc_params_create.md b/generated/test/docs/vc_vdc_params_create.md deleted file mode 100644 index 5529ac4..0000000 --- a/generated/test/docs/vc_vdc_params_create.md +++ /dev/null @@ -1,41 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - -
IDCodeTypeDescriptionConstraints
30organization_uiduuidДля создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director`ref_svc_id=19
335provider_vdcstringПриписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
746network_providerstring
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
361storage_configarray-map-fixed[{}]Первая политика в списке указывается как &quot;По умолчанию&quot;
397cpu_guaranteedinteger20Свойство нельзя изменить после созданияvalue_list=20, 50, 80
557cpu_allocatedinteger80штminvalue=1; maxvalue=1000
558mem_allocatedinteger200gbminvalue=1; maxvalue=4096
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/vc_vdc_params_modify.md b/generated/test/docs/vc_vdc_params_modify.md deleted file mode 100644 index 4bb0906..0000000 --- a/generated/test/docs/vc_vdc_params_modify.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_vc_vdc - -Service ID: `21` - -Service Name: Виртуальный датацентр (vDC) - -[Manual](vc_vdc.md) | [Create params](vc_vdc_params_create.md) | [Modify params](vc_vdc_params_modify.md) | [Output params](vc_vdc_outputs.md) | [Operations](vc_vdc_ops.md) | [Example](vc_vdc_example.md) - -## Modify params - - - - - - - -
IDCodeTypeDescriptionConstraints
560cpu_allocatedintegerштminvalue=1; maxvalue=999
561mem_allocatedintegergbminvalue=1; maxvalue=1024
562storage_configarray-map-fixedПервая политика в списке указывается как &quot;По умолчанию&quot;
diff --git a/generated/test/docs/vc_vm.md b/generated/test/docs/vc_vm.md deleted file mode 100644 index e0c84ef..0000000 --- a/generated/test/docs/vc_vm.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## MAN - -
-Виртуальная машина без каких-либо особенностей.
Данная услуга запускает vc_ip для выдачи белого адреса и подключения к ВМ -
diff --git a/generated/test/docs/vc_vm_example.md b/generated/test/docs/vc_vm_example.md deleted file mode 100644 index c05d7fe..0000000 --- a/generated/test/docs/vc_vm_example.md +++ /dev/null @@ -1,52 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Copy-ready manifest (`vc_vm_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_vm" "baza" { - vapp_uid = "TODO" # InstanceUid vApp. vApp должен быть создан - ip_space_name = "TODO" # Брать из свойств ресурсной платформы .vcd.ipSpace Имя IP-space для выделения внешнего IP (IP выделяется обязательно) - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - vm_name = "vm0001" # Имя ВМ. Не поддерживает спец-символы - vm_cpu = 2 # CPU - vm_ram = 2 # RAM (GB) - vm_disksize = 10 # Размер диска под сервис (GB) - template_name = "RockyLinux_9-16G" # ОС - access_ip_list = "79.111.119.78/32 185.247.187.1/32" # Вставить содержимое из 'curl ifconfig.io' IP адреса в CIDR формате через пробел для настройки аксес листов -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vm.baza.state_params["имя_ключа"] -nubes_vc_vm.baza.state_out["имя_ключа"] -nubes_vc_vm.baza.state_params_flat["имя_ключа"] -nubes_vc_vm.baza.state_out_flat["имя_ключа"] -nubes_vc_vm.baza.vault_secrets["имя_ключа"] -nubes_vc_vm.baza.vault_url -nubes_vc_vm.baza.vault_user_path -nubes_vc_vm.baza.vault_fields -``` diff --git a/generated/test/docs/vc_vm_ops.md b/generated/test/docs/vc_vm_ops.md deleted file mode 100644 index ff1e0cf..0000000 --- a/generated/test/docs/vc_vm_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vm_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vm_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/test/docs/vc_vm_outputs.md b/generated/test/docs/vc_vm_outputs.md deleted file mode 100644 index d5163ba..0000000 --- a/generated/test/docs/vc_vm_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/vc_vm_params.md b/generated/test/docs/vc_vm_params.md deleted file mode 100644 index 0ff6c3e..0000000 --- a/generated/test/docs/vc_vm_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Parameters - -- [Create params](vc_vm_params_create.md) -- [Modify params](vc_vm_params_modify.md) diff --git a/generated/test/docs/vc_vm_params_create.md b/generated/test/docs/vc_vm_params_create.md deleted file mode 100644 index 5bed0ba..0000000 --- a/generated/test/docs/vc_vm_params_create.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - -
IDCodeTypeDescriptionConstraints
33vapp_uiduuidInstanceUid vApp. vApp должен быть созданref_svc_id=26
406ip_space_namestringБрать из свойств ресурсной платформы
.vcd.ipSpace

Имя IP-space для выделения внешнего IP (IP выделяется обязательно)
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
35vm_namestringvm0001Имя ВМ. Не поддерживает спец-символыregex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
36vm_cpustring2CPU
37vm_ramstring2RAM (GB)
38vm_disksizestring10Размер диска под сервис (GB)
176template_namestringRockyLinux_9-16GОСvalue_list=RockyLinux_9-16G, OracleLinux_9-16G, Ubuntu_24-20G, Ubuntu_22-20G
177access_ip_liststring79.111.119.78/32 185.247.187.1/32IP адреса в CIDR формате через пробел для настройки аксес листов
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/vc_vm_params_modify.md b/generated/test/docs/vc_vm_params_modify.md deleted file mode 100644 index 0ec4505..0000000 --- a/generated/test/docs/vc_vm_params_modify.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vm - -Service ID: `23` - -Service Name: VM в Cloud Director (старый формат) (vc_vm) - -[Manual](vc_vm.md) | [Create params](vc_vm_params_create.md) | [Modify params](vc_vm_params_modify.md) | [Output params](vc_vm_outputs.md) | [Operations](vc_vm_ops.md) | [Example](vc_vm_example.md) - -## Modify params - - - - - - - - -
IDCodeTypeDescriptionConstraints
186vm_cpuintegerCPU
187vm_ramintegerRAM
188vm_disksizeintegerРазмер диска под сервис (GB)
189access_ip_liststringIP адреса в CIDR формате через пробел для настройки аксес листов
diff --git a/generated/test/docs/vc_vm_v2.md b/generated/test/docs/vc_vm_v2.md deleted file mode 100644 index ada3402..0000000 --- a/generated/test/docs/vc_vm_v2.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## MAN - -
-Manual not available. -
diff --git a/generated/test/docs/vc_vm_v2_example.md b/generated/test/docs/vc_vm_v2_example.md deleted file mode 100644 index 2902c17..0000000 --- a/generated/test/docs/vc_vm_v2_example.md +++ /dev/null @@ -1,45 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Copy-ready manifest (`vc_vm_v2_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_vm_v2" "baza" { - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - server_list_json = [{}] # Необходимо изменить vappUid и ipSpaceName Пример конфигурации взять по ссылке ниже Объект серверов вида [{}] (Map(Object)) Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2) -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vm_v2.baza.state_params["имя_ключа"] -nubes_vc_vm_v2.baza.state_out["имя_ключа"] -nubes_vc_vm_v2.baza.state_params_flat["имя_ключа"] -nubes_vc_vm_v2.baza.state_out_flat["имя_ключа"] -nubes_vc_vm_v2.baza.vault_secrets["имя_ключа"] -nubes_vc_vm_v2.baza.vault_url -nubes_vc_vm_v2.baza.vault_user_path -nubes_vc_vm_v2.baza.vault_fields -``` diff --git a/generated/test/docs/vc_vm_v2_ops.md b/generated/test/docs/vc_vm_v2_ops.md deleted file mode 100644 index 9d940af..0000000 --- a/generated/test/docs/vc_vm_v2_ops.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vm_v2_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vm_v2_params_modify.md) -- `resume` -- `suspend` diff --git a/generated/test/docs/vc_vm_v2_outputs.md b/generated/test/docs/vc_vm_v2_outputs.md deleted file mode 100644 index 3b9bace..0000000 --- a/generated/test/docs/vc_vm_v2_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/vc_vm_v2_params.md b/generated/test/docs/vc_vm_v2_params.md deleted file mode 100644 index e60c762..0000000 --- a/generated/test/docs/vc_vm_v2_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Parameters - -- [Create params](vc_vm_v2_params_create.md) -- [Modify params](vc_vm_v2_params_modify.md) diff --git a/generated/test/docs/vc_vm_v2_params_create.md b/generated/test/docs/vc_vm_v2_params_create.md deleted file mode 100644 index b1c20cc..0000000 --- a/generated/test/docs/vc_vm_v2_params_create.md +++ /dev/null @@ -1,32 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - -None. - -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - -
IDCodeTypeDefaultDescriptionConstraints
301server_list_jsonjson[{}]Необходимо изменить vappUid и ipSpaceName
Пример конфигурации взять по ссылке ниже

Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2)
maxlength=65536; minlength=10
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/vc_vm_v2_params_modify.md b/generated/test/docs/vc_vm_v2_params_modify.md deleted file mode 100644 index eedbec8..0000000 --- a/generated/test/docs/vc_vm_v2_params_modify.md +++ /dev/null @@ -1,15 +0,0 @@ -# Resource nubes_vc_vm_v2 - -Service ID: `27` - -Service Name: VM в Cloud Director (vc_vmV2) - -[Manual](vc_vm_v2.md) | [Create params](vc_vm_v2_params_create.md) | [Modify params](vc_vm_v2_params_modify.md) | [Output params](vc_vm_v2_outputs.md) | [Operations](vc_vm_v2_ops.md) | [Example](vc_vm_v2_example.md) - -## Modify params - - - - - -
IDCodeTypeDescriptionConstraints
302server_list_jsonjsonОбъект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2)
maxlength=65536; minlength=10
diff --git a/generated/test/docs/vc_vm_v3.md b/generated/test/docs/vc_vm_v3.md deleted file mode 100644 index 95856d8..0000000 --- a/generated/test/docs/vc_vm_v3.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## MAN - -
-# Документация по разворачиванию ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\ложь, определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed" (В нем не будет работать сбор метрик zabbix).

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики -
diff --git a/generated/test/docs/vc_vm_v3_example.md b/generated/test/docs/vc_vm_v3_example.md deleted file mode 100644 index 4b5d17a..0000000 --- a/generated/test/docs/vc_vm_v3_example.md +++ /dev/null @@ -1,53 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Copy-ready manifest (`vc_vm_v3_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vc_vm_v3" "baza" { - vapp_uid = "TODO" - ip_space_name = "TODO" - image_vm = "TODO" - user_public_key = "TODO" # Публичная часть SSH-Ключа для пользователя - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - vm_name = "web01" - vm_cpu = 1 # шт - vm_ram = 1 # Gb - user_login = "myuser" # Учётка SSH - access_port_list = ["22"] # По каким портам открыть доступ к ВМ. Порты 22, 10050 проставляются автоматически Пока доступно: 22 - SSH, 80 - HTTP, 443 - HTTPS, 10050 - ZABBIX -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vc_vm_v3.baza.state_params["имя_ключа"] -nubes_vc_vm_v3.baza.state_out["имя_ключа"] -nubes_vc_vm_v3.baza.state_params_flat["имя_ключа"] -nubes_vc_vm_v3.baza.state_out_flat["имя_ключа"] -nubes_vc_vm_v3.baza.vault_secrets["имя_ключа"] -nubes_vc_vm_v3.baza.vault_url -nubes_vc_vm_v3.baza.vault_user_path -nubes_vc_vm_v3.baza.vault_fields -``` diff --git a/generated/test/docs/vc_vm_v3_ops.md b/generated/test/docs/vc_vm_v3_ops.md deleted file mode 100644 index db02218..0000000 --- a/generated/test/docs/vc_vm_v3_ops.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vc_vm_v3_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vc_vm_v3_params_modify.md) -- `reconcile` -- `redeploy` -- `resume` -- `suspend` diff --git a/generated/test/docs/vc_vm_v3_outputs.md b/generated/test/docs/vc_vm_v3_outputs.md deleted file mode 100644 index d0ef2e1..0000000 --- a/generated/test/docs/vc_vm_v3_outputs.md +++ /dev/null @@ -1,30 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalConnect"]` -- `state_out_flat["fqdn"]` -- `state_out_flat["internalConnect"]` - diff --git a/generated/test/docs/vc_vm_v3_params.md b/generated/test/docs/vc_vm_v3_params.md deleted file mode 100644 index 9c63ad1..0000000 --- a/generated/test/docs/vc_vm_v3_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Parameters - -- [Create params](vc_vm_v3_params_create.md) -- [Modify params](vc_vm_v3_params_modify.md) diff --git a/generated/test/docs/vc_vm_v3_params_create.md b/generated/test/docs/vc_vm_v3_params_create.md deleted file mode 100644 index aff77f9..0000000 --- a/generated/test/docs/vc_vm_v3_params_create.md +++ /dev/null @@ -1,46 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
407vapp_uiduuidref_svc_id=26
411vm_diskintegerОсновной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму
regex=^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$
412ip_space_namestring
413access_ip_listjsonФормат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено [&quot;0.0.0.0/0&quot;]
regex=^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$
414image_vmstring
415cloud_inityamlМожно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов.
417user_public_keystringПубличная часть SSH-Ключа для пользователя
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - - - - -
IDCodeTypeDefaultDescriptionConstraints
408vm_namestringweb01regex=^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
409vm_cpuinteger1штminvalue=1; maxvalue=64
410vm_raminteger1Gbminvalue=1; maxvalue=256
416user_loginmyuserУчётка SSH
448access_port_liststring["22"]По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX
- -
-Параметры поведения (кратко)
-По умолчанию: `suspend_on_destroy = True`, `adopt_existing_on_create = False`.
-При `terraform destroy` или удалении ресурса из манифеста:
-- `suspend_on_destroy=true` — инстанс переводится в `Suspend` (не удаляется).
-- `suspend_on_destroy=false` — Terraform удаляет ресурс только из state.
-При `apply` флаг `adopt_existing_on_create` работает как авто-`import`:
-- `false` — если ресурс уже есть, будет ошибка.
-- `true` — Terraform может взять существующий инстанс под управление (`running` → adopt, `suspended` → resume+adopt при совпадении параметров).
-Важно: один инстанс должен быть только в одном state. Иначе получите конфликт управления. -
diff --git a/generated/test/docs/vc_vm_v3_params_modify.md b/generated/test/docs/vc_vm_v3_params_modify.md deleted file mode 100644 index e993928..0000000 --- a/generated/test/docs/vc_vm_v3_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vc_vm_v3 - -Service ID: `28` - -Service Name: Виртуальная машина - -[Manual](vc_vm_v3.md) | [Create params](vc_vm_v3_params_create.md) | [Modify params](vc_vm_v3_params_modify.md) | [Output params](vc_vm_v3_outputs.md) | [Operations](vc_vm_v3_ops.md) | [Example](vc_vm_v3_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
493vm_cpuintegerштminvalue=1; maxvalue=64
494vm_ramintegerGbminvalue=1; maxvalue=256
495vm_diskintegerОсновной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму
regex=^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$
496ip_space_namestringno-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev
value_list=no-needed, internet-antiddos-v1, internet-no-antiddos-v1, internet-ipv4-v1
497access_ip_listjsonФормат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено [&quot;0.0.0.0/0&quot;]
498access_port_listjsonФормат массива
По каким портам открыть доступ к ВМ.
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX
diff --git a/generated/test/docs/vcexternalip.md b/generated/test/docs/vcexternalip.md deleted file mode 100644 index 3fe625c..0000000 --- a/generated/test/docs/vcexternalip.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## MAN - -
-**Обычно эта услуга разворачивается автоматически при развёртывании более сложных услуг**
Вручную создавать можно, однако услуга требует много параметров, о которых можно просто не знать

Резервировать публичные IP адреса можно только после создания NGcloud Organization, NGcloud Виртуальный датацентр, NGcloud Каталог, Сетевой шлюз периметра.
Вы можете назначить IP адрес для существующего экземпляра сервиса. -
diff --git a/generated/test/docs/vcexternalip_example.md b/generated/test/docs/vcexternalip_example.md deleted file mode 100644 index 54ce0b3..0000000 --- a/generated/test/docs/vcexternalip_example.md +++ /dev/null @@ -1,51 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Copy-ready manifest (`vcexternalip_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vcexternalip" "baza" { - service_uid = "TODO" - internal_addr_access = "TODO" # Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true - from_service_namespace = "TODO" # Namespace составной услуги (для отображения правил FW) - ip_space_name = "TODO" # Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1) - resource_realm = "TODO" # Платформа для развертывания - - # Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте - dnat_create = true # Необходимо создать DNAT-правило. - internal_port_access = 5432 # Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vcexternalip.baza.state_params["имя_ключа"] -nubes_vcexternalip.baza.state_out["имя_ключа"] -nubes_vcexternalip.baza.state_params_flat["имя_ключа"] -nubes_vcexternalip.baza.state_out_flat["имя_ключа"] -nubes_vcexternalip.baza.vault_secrets["имя_ключа"] -nubes_vcexternalip.baza.vault_url -nubes_vcexternalip.baza.vault_user_path -nubes_vcexternalip.baza.vault_fields -``` diff --git a/generated/test/docs/vcexternalip_ops.md b/generated/test/docs/vcexternalip_ops.md deleted file mode 100644 index 5668481..0000000 --- a/generated/test/docs/vcexternalip_ops.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Operations - -- `create` — Создание кластера. Параметры: [Create params](vcexternalip_params_create.md) -- `delete` -- `modify` — Изменение кластера. Параметры: [Modify params](vcexternalip_params_modify.md) diff --git a/generated/test/docs/vcexternalip_outputs.md b/generated/test/docs/vcexternalip_outputs.md deleted file mode 100644 index aaa59e1..0000000 --- a/generated/test/docs/vcexternalip_outputs.md +++ /dev/null @@ -1,28 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов - -## Реальные поля из облака (running/suspended snapshot) - -Поля ниже получены из реальных инстансов этого сервиса в облаке. -Используйте их как готовые ключи для `state_out_flat` и `vault_secrets`. - -### `state_out_flat` ключи - -- `state_out_flat["externalIp"]` - diff --git a/generated/test/docs/vcexternalip_params.md b/generated/test/docs/vcexternalip_params.md deleted file mode 100644 index 1db2fcc..0000000 --- a/generated/test/docs/vcexternalip_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Parameters - -- [Create params](vcexternalip_params_create.md) -- [Modify params](vcexternalip_params_modify.md) diff --git a/generated/test/docs/vcexternalip_params_create.md b/generated/test/docs/vcexternalip_params_create.md deleted file mode 100644 index 995a3b8..0000000 --- a/generated/test/docs/vcexternalip_params_create.md +++ /dev/null @@ -1,36 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - - - - - - - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
140service_uidstring
143snat_createbooleanНеобходимо создать SNAT-правило.
144internal_addr_accessstringВнутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true
324from_service_namespacestringNamespace составной услуги (для отображения правил FW)
325from_service_cloud_edge_namestringEdge составной услуги (указывать, если resourceRealm связан с CloudDirector)
326from_service_cloud_vdc_nameVdc составной услуги (указывать, если resourceRealm связан с CloudDirector)
327from_service_cloud_org_namestringOrg составной услуги (указывать, если resourceRealm связан с CloudDirector)
328from_service_cloud_vmware_urlstringApi-Url составной услуги (указывать, если resourceRealm связан с CloudDirector)
336ip_space_namestringТип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1)
488resource_realmstringПлатформа для развертыванияfunc=getAvailableResourceRealms
624from_service_cloud_edge_scopestring
626from_service_vdc_group_namestring
- -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** - - - - - -
IDCodeTypeDefaultDescriptionConstraints
141dnat_createbooleantrueНеобходимо создать DNAT-правило.
142internal_port_accessstring5432Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
diff --git a/generated/test/docs/vcexternalip_params_modify.md b/generated/test/docs/vcexternalip_params_modify.md deleted file mode 100644 index f17b66c..0000000 --- a/generated/test/docs/vcexternalip_params_modify.md +++ /dev/null @@ -1,20 +0,0 @@ -# Resource nubes_vcexternalip - -Service ID: `25` - -Service Name: Публичные IP адреса - -[Manual](vcexternalip.md) | [Create params](vcexternalip_params_create.md) | [Modify params](vcexternalip_params_modify.md) | [Output params](vcexternalip_outputs.md) | [Operations](vcexternalip_ops.md) | [Example](vcexternalip_example.md) - -## Modify params - - - - - - - - - - -
IDCodeTypeDescriptionConstraints
627service_uidstring
628ip_space_namestring
629dnat_createboolean
630snat_createboolean
631internal_port_accessstring
632internal_addr_accessstring
diff --git a/generated/test/docs/vmpostgre.md b/generated/test/docs/vmpostgre.md deleted file mode 100644 index 31d8dad..0000000 --- a/generated/test/docs/vmpostgre.md +++ /dev/null @@ -1,13 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## MAN - -
-Сервис настройки PostgreSQL для виртуальной машины.
Требует наличия ВМ -
diff --git a/generated/test/docs/vmpostgre_example.md b/generated/test/docs/vmpostgre_example.md deleted file mode 100644 index 12c950d..0000000 --- a/generated/test/docs/vmpostgre_example.md +++ /dev/null @@ -1,42 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Copy-ready manifest (`vmpostgre_main.tf`) - -```hcl -terraform { - required_providers { - nubes = { - source = "terra.k8c.ru/nubes/nubes" - version = "5.0.75" - } - } -} - -# Токен доступа api_token к Nubes API — замените на реальный. -provider "nubes" { - api_token = "token_***" - api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc" -} -resource "nubes_vmpostgre" "baza" { -} -``` - -## Outputs usage - -```hcl -# Выходные параметры можно использовать как -nubes_vmpostgre.baza.state_params["имя_ключа"] -nubes_vmpostgre.baza.state_out["имя_ключа"] -nubes_vmpostgre.baza.state_params_flat["имя_ключа"] -nubes_vmpostgre.baza.state_out_flat["имя_ключа"] -nubes_vmpostgre.baza.vault_secrets["имя_ключа"] -nubes_vmpostgre.baza.vault_url -nubes_vmpostgre.baza.vault_user_path -nubes_vmpostgre.baza.vault_fields -``` diff --git a/generated/test/docs/vmpostgre_ops.md b/generated/test/docs/vmpostgre_ops.md deleted file mode 100644 index a83096e..0000000 --- a/generated/test/docs/vmpostgre_ops.md +++ /dev/null @@ -1,10 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Operations - diff --git a/generated/test/docs/vmpostgre_outputs.md b/generated/test/docs/vmpostgre_outputs.md deleted file mode 100644 index 5c8d505..0000000 --- a/generated/test/docs/vmpostgre_outputs.md +++ /dev/null @@ -1,18 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Output params - -- `state_params` (map) — параметры, отправленные в API при создании/изменении -- `state_out` (map) — ответ API с результатами/выходными значениями -- `state_params_flat` (map) — параметры в плоском виде (ключи с путями) -- `state_out_flat` (map) — ответы в плоском виде (ключи с путями) -- `vault_secrets` (map) — секреты, записанные в Vault для ресурса -- `vault_url` (string) — адрес Vault для ресурса -- `vault_user_path` (string) — путь пользователя в Vault -- `vault_fields` (list) — список ключей доступных секретов diff --git a/generated/test/docs/vmpostgre_params.md b/generated/test/docs/vmpostgre_params.md deleted file mode 100644 index 8b28da6..0000000 --- a/generated/test/docs/vmpostgre_params.md +++ /dev/null @@ -1,12 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Parameters - -- [Create params](vmpostgre_params_create.md) -- [Modify params](vmpostgre_params_modify.md) diff --git a/generated/test/docs/vmpostgre_params_create.md b/generated/test/docs/vmpostgre_params_create.md deleted file mode 100644 index f140764..0000000 --- a/generated/test/docs/vmpostgre_params_create.md +++ /dev/null @@ -1,16 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Create params - -**Обязательные параметры (вводимые пользователем)** - -None. - -**Параметры, имеющие значение по умолчанию, если не меняете - эти параметры не обязательно прописывать в манифесте** -None. diff --git a/generated/test/docs/vmpostgre_params_modify.md b/generated/test/docs/vmpostgre_params_modify.md deleted file mode 100644 index 9ce30ad..0000000 --- a/generated/test/docs/vmpostgre_params_modify.md +++ /dev/null @@ -1,11 +0,0 @@ -# Resource nubes_vmpostgre - -Service ID: `32` - -Service Name: vc_vm_postgresql_std - -[Manual](vmpostgre.md) | [Create params](vmpostgre_params_create.md) | [Modify params](vmpostgre_params_modify.md) | [Output params](vmpostgre_outputs.md) | [Operations](vmpostgre_ops.md) | [Example](vmpostgre_example.md) - -## Modify params - -None. diff --git a/generated/test/go/.gitkeep b/generated/test/go/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/test/go/100_openwhisk_resource.go b/generated/test/go/100_openwhisk_resource.go deleted file mode 100644 index bdc6724..0000000 --- a/generated/test/go/100_openwhisk_resource.go +++ /dev/null @@ -1,317 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: openwhisk -// Service ID: 100 - -var _ resource.Resource = &OpenwhiskResource{} -var _ resource.ResourceWithModifyPlan = &OpenwhiskResource{} -var _ resource.ResourceWithImportState = &OpenwhiskResource{} - -type OpenwhiskResource struct { - client *core.UniversalClient -} - -type OpenwhiskModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewOpenwhiskResource() resource.Resource { - return &OpenwhiskResource{} -} - -func (r *OpenwhiskResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_openwhisk" -} - -func (r *OpenwhiskResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *OpenwhiskResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *OpenwhiskModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *OpenwhiskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan OpenwhiskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{} - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 100, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *OpenwhiskResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data OpenwhiskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 100, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{} - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 100, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 100, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *OpenwhiskResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state OpenwhiskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 100, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *OpenwhiskResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan OpenwhiskModel - var state OpenwhiskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 100, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *OpenwhiskResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state OpenwhiskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *OpenwhiskResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *OpenwhiskResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/110_dnszone_resource.go b/generated/test/go/110_dnszone_resource.go deleted file mode 100644 index 0826696..0000000 --- a/generated/test/go/110_dnszone_resource.go +++ /dev/null @@ -1,501 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dnszone -// Service ID: 110 - -var _ resource.Resource = &DnszoneResource{} -var _ resource.ResourceWithModifyPlan = &DnszoneResource{} -var _ resource.ResourceWithImportState = &DnszoneResource{} - -type DnszoneResource struct { - client *core.UniversalClient -} - -type DnszoneModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ResourceRealm types.String `tfsdk:"resource_realm"` - ZoneEmail types.String `tfsdk:"zone_email"` - ZoneKind types.String `tfsdk:"zone_kind"` - ZoneMastersForSlave types.String `tfsdk:"zone_masters_for_slave"` - ZoneName types.String `tfsdk:"zone_name"` - ZoneTimeToExpire types.String `tfsdk:"zone_time_to_expire"` - ZoneTimeToLive types.String `tfsdk:"zone_time_to_live"` - ZoneTimeToRefresh types.String `tfsdk:"zone_time_to_refresh"` - ZoneTimeToRetry types.String `tfsdk:"zone_time_to_retry"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDnszoneResource() resource.Resource { - return &DnszoneResource{} -} - -func (r *DnszoneResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dnszone" -} - -func (r *DnszoneResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "zone_email": schema.StringAttribute{Required: true, MarkdownDescription: "Контактный e-mail Не изменяется после создания."}, - "zone_kind": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("NATIVE"), MarkdownDescription: "Тип зоны Не изменяется после создания."}, - "zone_masters_for_slave": schema.StringAttribute{Optional: true, MarkdownDescription: "Использовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов Не изменяется после создания."}, - "zone_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя зоны Не изменяется после создания."}, - "zone_time_to_expire": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("3600000"), MarkdownDescription: "Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным Не изменяется после создания."}, - "zone_time_to_live": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("86400"), MarkdownDescription: "Время, в течение которого информация будет кешироваться другими DNS-серверами Не изменяется после создания."}, - "zone_time_to_refresh": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("86400"), MarkdownDescription: "Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов Не изменяется после создания."}, - "zone_time_to_retry": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("7200"), MarkdownDescription: "Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DnszoneResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DnszoneModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneEmail.IsNull() && !plan.ZoneEmail.IsUnknown() && !state.ZoneEmail.IsNull() && !state.ZoneEmail.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneEmail.ValueString(), state.ZoneEmail.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_email", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneKind.IsNull() && !plan.ZoneKind.IsUnknown() && !state.ZoneKind.IsNull() && !state.ZoneKind.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneKind.ValueString(), state.ZoneKind.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_kind", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneMastersForSlave.IsNull() && !plan.ZoneMastersForSlave.IsUnknown() && !state.ZoneMastersForSlave.IsNull() && !state.ZoneMastersForSlave.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneMastersForSlave.ValueString(), state.ZoneMastersForSlave.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_masters_for_slave", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneName.IsNull() && !plan.ZoneName.IsUnknown() && !state.ZoneName.IsNull() && !state.ZoneName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneName.ValueString(), state.ZoneName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToExpire.IsNull() && !plan.ZoneTimeToExpire.IsUnknown() && !state.ZoneTimeToExpire.IsNull() && !state.ZoneTimeToExpire.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneTimeToExpire.ValueString(), state.ZoneTimeToExpire.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_expire", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToLive.IsNull() && !plan.ZoneTimeToLive.IsUnknown() && !state.ZoneTimeToLive.IsNull() && !state.ZoneTimeToLive.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneTimeToLive.ValueString(), state.ZoneTimeToLive.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_live", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToRefresh.IsNull() && !plan.ZoneTimeToRefresh.IsUnknown() && !state.ZoneTimeToRefresh.IsNull() && !state.ZoneTimeToRefresh.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneTimeToRefresh.ValueString(), state.ZoneTimeToRefresh.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_refresh", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneTimeToRetry.IsNull() && !plan.ZoneTimeToRetry.IsUnknown() && !state.ZoneTimeToRetry.IsNull() && !state.ZoneTimeToRetry.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneTimeToRetry.ValueString(), state.ZoneTimeToRetry.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_time_to_retry", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - if config.ZoneEmail.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "zone_email is required.") - return - } - if config.ZoneEmail.IsUnknown() { - return - } - if config.ZoneName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "zone_name is required.") - return - } - if config.ZoneName.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 66: resources_core.FormatString(config.ZoneEmail), - 67: resources_core.FormatString(config.ZoneName), - 68: resources_core.FormatString(config.ZoneKind), - 69: resources_core.FormatString(config.ZoneMastersForSlave), - 70: resources_core.FormatString(config.ZoneTimeToRefresh), - 71: resources_core.FormatString(config.ZoneTimeToRetry), - 72: resources_core.FormatString(config.ZoneTimeToExpire), - 73: resources_core.FormatString(config.ZoneTimeToLive), - 284: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 110, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DnszoneResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.ZoneEmail.IsNull() || data.ZoneEmail.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_email is required.") - return - } - if data.ZoneName.IsNull() || data.ZoneName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_name is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 110, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 66: resources_core.FormatString(data.ZoneEmail), - 67: resources_core.FormatString(data.ZoneName), - 68: resources_core.FormatString(data.ZoneKind), - 69: resources_core.FormatString(data.ZoneMastersForSlave), - 70: resources_core.FormatString(data.ZoneTimeToRefresh), - 71: resources_core.FormatString(data.ZoneTimeToRetry), - 72: resources_core.FormatString(data.ZoneTimeToExpire), - 73: resources_core.FormatString(data.ZoneTimeToLive), - 284: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 110, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 110, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnszoneResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 110, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DnszoneResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DnszoneModel - var state DnszoneModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 110, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "zoneEmail", Field: "ZoneEmail", Type: "string"}, - {Code: "zoneKind", Field: "ZoneKind", Type: "string"}, - {Code: "zoneMastersForSlave", Field: "ZoneMastersForSlave", Type: "string"}, - {Code: "zoneName", Field: "ZoneName", Type: "string"}, - {Code: "zoneTimeToExpire", Field: "ZoneTimeToExpire", Type: "string"}, - {Code: "zoneTimeToLive", Field: "ZoneTimeToLive", Type: "string"}, - {Code: "zoneTimeToRefresh", Field: "ZoneTimeToRefresh", Type: "string"}, - {Code: "zoneTimeToRetry", Field: "ZoneTimeToRetry", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnszoneResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DnszoneModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DnszoneResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DnszoneResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/111_dnsrecord_resource.go b/generated/test/go/111_dnsrecord_resource.go deleted file mode 100644 index bb64255..0000000 --- a/generated/test/go/111_dnsrecord_resource.go +++ /dev/null @@ -1,541 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dnsrecord -// Service ID: 111 - -var _ resource.Resource = &DnsrecordResource{} -var _ resource.ResourceWithModifyPlan = &DnsrecordResource{} -var _ resource.ResourceWithImportState = &DnsrecordResource{} - -type DnsrecordResource struct { - client *core.UniversalClient -} - -type DnsrecordModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - RecordInput types.String `tfsdk:"record_input"` - RecordName types.String `tfsdk:"record_name"` - RecordTTL types.Int64 `tfsdk:"record_t_t_l"` - RecordType types.String `tfsdk:"record_type"` - ZoneUid types.String `tfsdk:"zone_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDnsrecordResource() resource.Resource { - return &DnsrecordResource{} -} - -func (r *DnsrecordResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dnsrecord" -} - -func (r *DnsrecordResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "record_input": schema.StringAttribute{Required: true, MarkdownDescription: "Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP"}, - "record_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя записи. Имя зоны в конце проставляется автоматически Не изменяется после создания."}, - "record_t_t_l": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(3600), MarkdownDescription: "Time-to-Leave записи. Раз в какое время запись будет обновлена Не изменяется после создания."}, - "record_type": schema.StringAttribute{Required: true, MarkdownDescription: "Тип DNS-записи Не изменяется после создания."}, - "zone_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UUID экземпляра услуги DNS-зоны Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DnsrecordResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DnsrecordModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.RecordName.IsNull() && !plan.RecordName.IsUnknown() && !state.RecordName.IsNull() && !state.RecordName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.RecordName.ValueString(), state.RecordName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить record_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RecordTTL.IsNull() && !plan.RecordTTL.IsUnknown() && !state.RecordTTL.IsNull() && !state.RecordTTL.IsUnknown() { - if plan.RecordTTL.ValueInt64() != state.RecordTTL.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить record_t_t_l", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RecordType.IsNull() && !plan.RecordType.IsUnknown() && !state.RecordType.IsNull() && !state.RecordType.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.RecordType.ValueString(), state.RecordType.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить record_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ZoneUid.IsNull() && !plan.ZoneUid.IsUnknown() && !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ZoneUid.ValueString(), state.ZoneUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить zone_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.RecordInput.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "record_input is required.") - return - } - if config.RecordInput.IsUnknown() { - return - } - if config.RecordName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "record_name is required.") - return - } - if config.RecordName.IsUnknown() { - return - } - if config.RecordType.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "record_type is required.") - return - } - if config.RecordType.IsUnknown() { - return - } - if config.ZoneUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "zone_uid is required.") - return - } - if config.ZoneUid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.ZoneUid.IsNull() && !config.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 109, config.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != config.ZoneUid.ValueString() { - config.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - params := map[int]string{ - 75: resources_core.FormatString(config.ZoneUid), - 76: resources_core.FormatString(config.RecordType), - 77: resources_core.FormatString(config.RecordName), - 78: resources_core.FormatString(config.RecordInput), - 450: resources_core.FormatInt64(config.RecordTTL), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 111, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DnsrecordResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.RecordInput.IsNull() || data.RecordInput.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_input is required.") - return - } - if data.RecordName.IsNull() || data.RecordName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_name is required.") - return - } - if data.RecordType.IsNull() || data.RecordType.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "record_type is required.") - return - } - if data.ZoneUid.IsNull() || data.ZoneUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "zone_uid is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalZoneUid := data.ZoneUid - if !data.ZoneUid.IsNull() && !data.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 109, data.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedZoneUid != "" && resolvedZoneUid != data.ZoneUid.ValueString() { - data.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 111, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 75: resources_core.FormatString(data.ZoneUid), - 76: resources_core.FormatString(data.RecordType), - 77: resources_core.FormatString(data.RecordName), - 78: resources_core.FormatString(data.RecordInput), - 450: resources_core.FormatInt64(data.RecordTTL), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 111, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 111, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 109, state.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != state.ZoneUid.ValueString() { - state.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalZoneUid.IsNull() && !originalZoneUid.IsUnknown() && !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - if strings.EqualFold(state.ZoneUid.ValueString(), originalZoneUid.ValueString()) { - state.ZoneUid = originalZoneUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnsrecordResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 111, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.ZoneUid.IsNull() && !newState.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 109, newState.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != newState.ZoneUid.ValueString() { - newState.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() && !newState.ZoneUid.IsNull() && !newState.ZoneUid.IsUnknown() { - if strings.EqualFold(newState.ZoneUid.ValueString(), state.ZoneUid.ValueString()) { - newState.ZoneUid = state.ZoneUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DnsrecordResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DnsrecordModel - var state DnsrecordModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.RecordInput.IsNull() != state.RecordInput.IsNull() || plan.RecordInput.IsUnknown() != state.RecordInput.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.RecordInput.IsNull() && !plan.RecordInput.IsUnknown() && !state.RecordInput.IsNull() && !state.RecordInput.IsUnknown() { - if !strings.EqualFold(plan.RecordInput.ValueString(), state.RecordInput.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 256: resources_core.FormatString(plan.RecordInput), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 111, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "recordInput", Field: "RecordInput", Type: "string"}, - {Code: "recordName", Field: "RecordName", Type: "string"}, - {Code: "recordTTL", Field: "RecordTTL", Type: "int64"}, - {Code: "recordType", Field: "RecordType", Type: "string"}, - {Code: "zoneUid", Field: "ZoneUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - resolvedZoneUid, err := r.client.ResolveRefSvcParamValue(ctx, 109, state.ZoneUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve zone_uid", err.Error()) - } else if resolvedZoneUid != "" && resolvedZoneUid != state.ZoneUid.ValueString() { - state.ZoneUid = types.StringValue(resolvedZoneUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.ZoneUid.IsNull() && !plan.ZoneUid.IsUnknown() && !state.ZoneUid.IsNull() && !state.ZoneUid.IsUnknown() { - if strings.EqualFold(state.ZoneUid.ValueString(), plan.ZoneUid.ValueString()) { - state.ZoneUid = plan.ZoneUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DnsrecordResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DnsrecordModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DnsrecordResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DnsrecordResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/112_tenant_resource.go b/generated/test/go/112_tenant_resource.go deleted file mode 100644 index 6838a3b..0000000 --- a/generated/test/go/112_tenant_resource.go +++ /dev/null @@ -1,377 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: tenant -// Service ID: 112 - -var _ resource.Resource = &TenantResource{} -var _ resource.ResourceWithModifyPlan = &TenantResource{} -var _ resource.ResourceWithImportState = &TenantResource{} - -type TenantResource struct { - client *core.UniversalClient -} - -type TenantModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - GrafanaOrgName types.String `tfsdk:"grafana_org_name"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewTenantResource() resource.Resource { - return &TenantResource{} -} - -func (r *TenantResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_tenant" -} - -func (r *TenantResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "grafana_org_name": schema.StringAttribute{Required: true, MarkdownDescription: "WZ-Код клиента Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *TenantResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *TenantModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *TenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan TenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.GrafanaOrgName.IsNull() && !plan.GrafanaOrgName.IsUnknown() && !state.GrafanaOrgName.IsNull() && !state.GrafanaOrgName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.GrafanaOrgName.ValueString(), state.GrafanaOrgName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить grafana_org_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.GrafanaOrgName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "grafana_org_name is required.") - return - } - if config.GrafanaOrgName.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 239: resources_core.FormatString(config.GrafanaOrgName), - 240: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 112, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *TenantResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data TenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.GrafanaOrgName.IsNull() || data.GrafanaOrgName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "grafana_org_name is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 112, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 239: resources_core.FormatString(data.GrafanaOrgName), - 240: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 112, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 112, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "grafanaOrgName", Field: "GrafanaOrgName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TenantResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state TenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 112, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "grafanaOrgName", Field: "GrafanaOrgName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *TenantResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan TenantModel - var state TenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 112, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "grafanaOrgName", Field: "GrafanaOrgName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TenantResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state TenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *TenantResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *TenantResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/113_vc_complex_resource.go b/generated/test/go/113_vc_complex_resource.go deleted file mode 100644 index dfb13ff..0000000 --- a/generated/test/go/113_vc_complex_resource.go +++ /dev/null @@ -1,569 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_complex -// Service ID: 113 - -var _ resource.Resource = &VcComplexResource{} -var _ resource.ResourceWithModifyPlan = &VcComplexResource{} -var _ resource.ResourceWithImportState = &VcComplexResource{} - -type VcComplexResource struct { - client *core.UniversalClient -} - -type VcComplexModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - CpuAllocated types.String `tfsdk:"cpu_allocated"` - CpuGuaranteed types.Int64 `tfsdk:"cpu_guaranteed"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - MemAllocated types.Int64 `tfsdk:"mem_allocated"` - MemGuaranteed types.Int64 `tfsdk:"mem_guaranteed"` - NeedEnableAVI types.Bool `tfsdk:"need_enable_a_v_i"` - NeedExternalAddressSNAT types.Bool `tfsdk:"need_external_address_s_n_a_t"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SegroupName types.String `tfsdk:"segroup_name"` - StorageConfig types.String `tfsdk:"storage_config"` - VIPCount types.Int64 `tfsdk:"v_i_p_count"` - VappName types.String `tfsdk:"vapp_name"` - VdcNetworkPool types.String `tfsdk:"vdc_network_pool"` - VdcProviderGateway types.String `tfsdk:"vdc_provider_gateway"` - VirtualServicesCount types.String `tfsdk:"virtual_services_count"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcComplexResource() resource.Resource { - return &VcComplexResource{} -} - -func (r *VcComplexResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_complex" -} - -func (r *VcComplexResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "cpu_allocated": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("1"), MarkdownDescription: "шт Не изменяется после создания."}, - "cpu_guaranteed": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "Не изменяется после создания."}, - "ip_space_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("internet-ipv4-v1"), MarkdownDescription: "Имя ip Space для внешнего IP. Целесообразнее брать самый дешёвый, так как это vip для исходящего трафика. Необходимо задавать если включен needExternalAddressSNAT Не изменяется после создания."}, - "mem_allocated": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "gb Не изменяется после создания."}, - "mem_guaranteed": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "Не изменяется после создания."}, - "need_enable_a_v_i": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включает AVI в Cloud Director Не изменяется после создания."}, - "need_external_address_s_n_a_t": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Выделяет внешний IP на Edge. Используется для SNAT всего трафика Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "segroup_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("SEGROUP-SANDBOX-CL1-SHARED-01"), MarkdownDescription: "Наименование segroup, в котором будут выделяться пулы на AVI Не изменяется после создания."}, - "storage_config": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{\"name\": \"\", \"size\": 1024}]"), MarkdownDescription: "Описывается как массив объектов, где описывается имя политики и её размер Не изменяется после создания.", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "v_i_p_count": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "ш Не изменяется после создания."}, - "vapp_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя vApp Не изменяется после создания."}, - "vdc_network_pool": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("nsxt-sandbox-geneve-np"), MarkdownDescription: "Не изменяется после создания."}, - "vdc_provider_gateway": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("sandbox-v1cl1-pvdc"), MarkdownDescription: "Взять из свойств ресурсной платформы.
Путь .vcd.providerVdc - взять KEY

providerGateway Cloud Director. Влияет ресурсы будут предоставлены. Является полем (List<String>) в свойствах рес. платформы ЛК, но сам параметр передаётся только как один String Не изменяется после создания."}, - "virtual_services_count": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("1"), MarkdownDescription: "Кол-во виртуальных сервисов, которые выделяются на AVI. Во избежании коллапса пока выделяется до 4 Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcComplexResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcComplexModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.CpuAllocated.IsNull() && !plan.CpuAllocated.IsUnknown() && !state.CpuAllocated.IsNull() && !state.CpuAllocated.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.CpuAllocated.ValueString(), state.CpuAllocated.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить cpu_allocated", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.CpuGuaranteed.IsNull() && !plan.CpuGuaranteed.IsUnknown() && !state.CpuGuaranteed.IsNull() && !state.CpuGuaranteed.IsUnknown() { - if plan.CpuGuaranteed.ValueInt64() != state.CpuGuaranteed.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить cpu_guaranteed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.IpSpaceName.ValueString(), state.IpSpaceName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MemAllocated.IsNull() && !plan.MemAllocated.IsUnknown() && !state.MemAllocated.IsNull() && !state.MemAllocated.IsUnknown() { - if plan.MemAllocated.ValueInt64() != state.MemAllocated.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить mem_allocated", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MemGuaranteed.IsNull() && !plan.MemGuaranteed.IsUnknown() && !state.MemGuaranteed.IsNull() && !state.MemGuaranteed.IsUnknown() { - if plan.MemGuaranteed.ValueInt64() != state.MemGuaranteed.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить mem_guaranteed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedEnableAVI.IsNull() && !plan.NeedEnableAVI.IsUnknown() && !state.NeedEnableAVI.IsNull() && !state.NeedEnableAVI.IsUnknown() { - if plan.NeedEnableAVI.ValueBool() != state.NeedEnableAVI.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_enable_a_v_i", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NeedExternalAddressSNAT.IsNull() && !plan.NeedExternalAddressSNAT.IsUnknown() && !state.NeedExternalAddressSNAT.IsNull() && !state.NeedExternalAddressSNAT.IsUnknown() { - if plan.NeedExternalAddressSNAT.ValueBool() != state.NeedExternalAddressSNAT.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить need_external_address_s_n_a_t", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.SegroupName.IsNull() && !plan.SegroupName.IsUnknown() && !state.SegroupName.IsNull() && !state.SegroupName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.SegroupName.ValueString(), state.SegroupName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить segroup_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.StorageConfig.IsNull() && !plan.StorageConfig.IsUnknown() && !state.StorageConfig.IsNull() && !state.StorageConfig.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StorageConfig.ValueString(), state.StorageConfig.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить storage_config", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VIPCount.IsNull() && !plan.VIPCount.IsUnknown() && !state.VIPCount.IsNull() && !state.VIPCount.IsUnknown() { - if plan.VIPCount.ValueInt64() != state.VIPCount.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить v_i_p_count", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappName.IsNull() && !plan.VappName.IsUnknown() && !state.VappName.IsNull() && !state.VappName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VappName.ValueString(), state.VappName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vapp_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcNetworkPool.IsNull() && !plan.VdcNetworkPool.IsUnknown() && !state.VdcNetworkPool.IsNull() && !state.VdcNetworkPool.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VdcNetworkPool.ValueString(), state.VdcNetworkPool.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vdc_network_pool", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcProviderGateway.IsNull() && !plan.VdcProviderGateway.IsUnknown() && !state.VdcProviderGateway.IsNull() && !state.VdcProviderGateway.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VdcProviderGateway.ValueString(), state.VdcProviderGateway.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vdc_provider_gateway", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VirtualServicesCount.IsNull() && !plan.VirtualServicesCount.IsUnknown() && !state.VirtualServicesCount.IsNull() && !state.VirtualServicesCount.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VirtualServicesCount.ValueString(), state.VirtualServicesCount.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить virtual_services_count", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - if config.VappName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - if config.VappName.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 332: resources_core.FormatString(config.ResourceRealm), - 334: resources_core.FormatString(config.VappName), - 358: resources_core.FormatString(config.VdcProviderGateway), - 359: resources_core.FormatString(config.VirtualServicesCount), - 360: resources_core.FormatString(config.IpSpaceName), - 399: resources_core.FormatString(config.StorageConfig), - 400: resources_core.FormatString(config.VdcNetworkPool), - 401: resources_core.FormatInt64(config.CpuGuaranteed), - 402: resources_core.FormatInt64(config.MemGuaranteed), - 403: resources_core.FormatString(config.SegroupName), - 404: resources_core.FormatBool(config.NeedExternalAddressSNAT), - 405: resources_core.FormatBool(config.NeedEnableAVI), - 566: resources_core.FormatString(config.CpuAllocated), - 567: resources_core.FormatInt64(config.MemAllocated), - 568: resources_core.FormatInt64(config.VIPCount), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 113, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcComplexResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.VappName.IsNull() || data.VappName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 113, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 332: resources_core.FormatString(data.ResourceRealm), - 334: resources_core.FormatString(data.VappName), - 358: resources_core.FormatString(data.VdcProviderGateway), - 359: resources_core.FormatString(data.VirtualServicesCount), - 360: resources_core.FormatString(data.IpSpaceName), - 399: resources_core.FormatString(data.StorageConfig), - 400: resources_core.FormatString(data.VdcNetworkPool), - 401: resources_core.FormatInt64(data.CpuGuaranteed), - 402: resources_core.FormatInt64(data.MemGuaranteed), - 403: resources_core.FormatString(data.SegroupName), - 404: resources_core.FormatBool(data.NeedExternalAddressSNAT), - 405: resources_core.FormatBool(data.NeedEnableAVI), - 566: resources_core.FormatString(data.CpuAllocated), - 567: resources_core.FormatInt64(data.MemAllocated), - 568: resources_core.FormatInt64(data.VIPCount), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 113, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 113, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "string"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "segroupName", Field: "SegroupName", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - {Code: "vIPCount", Field: "VIPCount", Type: "int64"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcNetworkPool", Field: "VdcNetworkPool", Type: "string"}, - {Code: "vdcProviderGateway", Field: "VdcProviderGateway", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcComplexResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 113, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "string"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "segroupName", Field: "SegroupName", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - {Code: "vIPCount", Field: "VIPCount", Type: "int64"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcNetworkPool", Field: "VdcNetworkPool", Type: "string"}, - {Code: "vdcProviderGateway", Field: "VdcProviderGateway", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcComplexResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcComplexModel - var state VcComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 113, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "string"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "memGuaranteed", Field: "MemGuaranteed", Type: "int64"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "needExternalAddressSNAT", Field: "NeedExternalAddressSNAT", Type: "bool"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "segroupName", Field: "SegroupName", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - {Code: "vIPCount", Field: "VIPCount", Type: "int64"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcNetworkPool", Field: "VdcNetworkPool", Type: "string"}, - {Code: "vdcProviderGateway", Field: "VdcProviderGateway", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcComplexResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcComplexResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcComplexResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/114_gitea_complex_resource.go b/generated/test/go/114_gitea_complex_resource.go deleted file mode 100644 index dd9824e..0000000 --- a/generated/test/go/114_gitea_complex_resource.go +++ /dev/null @@ -1,317 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: gitea_complex -// Service ID: 114 - -var _ resource.Resource = &GiteaComplexResource{} -var _ resource.ResourceWithModifyPlan = &GiteaComplexResource{} -var _ resource.ResourceWithImportState = &GiteaComplexResource{} - -type GiteaComplexResource struct { - client *core.UniversalClient -} - -type GiteaComplexModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewGiteaComplexResource() resource.Resource { - return &GiteaComplexResource{} -} - -func (r *GiteaComplexResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_gitea_complex" -} - -func (r *GiteaComplexResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *GiteaComplexResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *GiteaComplexModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *GiteaComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan GiteaComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{} - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 114, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *GiteaComplexResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data GiteaComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 114, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{} - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 114, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 114, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaComplexResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state GiteaComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 114, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *GiteaComplexResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan GiteaComplexModel - var state GiteaComplexModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 114, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaComplexResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state GiteaComplexModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *GiteaComplexResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *GiteaComplexResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/115_mariadb_database_resource.go b/generated/test/go/115_mariadb_database_resource.go deleted file mode 100644 index 59dd751..0000000 --- a/generated/test/go/115_mariadb_database_resource.go +++ /dev/null @@ -1,347 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mariadb -// Subresource: database - -var _ resource.Resource = &MariadbDatabaseResource{} - -// MariadbDatabaseResource manages a subresource via operations. -type MariadbDatabaseResource struct { - client *core.UniversalClient -} - -type MariadbDatabaseModel struct { - ID types.String `tfsdk:"id"` - MariadbID types.String `tfsdk:"mariadb_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DbName types.String `tfsdk:"db_name"` -} - -func NewMariadbDatabaseResource() resource.Resource { - return &MariadbDatabaseResource{} -} - -func (r *MariadbDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mariadb_database" -} - -func (r *MariadbDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "mariadb_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "db_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("db-"), MarkdownDescription: "Пример: `db01` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MariadbDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan MariadbDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.MariadbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - } - identityCodes := []string{ - "dbName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MariadbDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MariadbDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MariadbDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state MariadbDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.MariadbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MariadbDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MariadbDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_database" == "" { - return - } - - instanceUID := strings.TrimSpace(state.MariadbID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "dbName": resources_core.FormatString(state.DbName), - } - identityCodes := []string{ - "dbName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "dbName": resources_core.FormatString(state.DbName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_database", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *MariadbDatabaseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/115_mariadb_resource.go b/generated/test/go/115_mariadb_resource.go deleted file mode 100644 index 2ae9571..0000000 --- a/generated/test/go/115_mariadb_resource.go +++ /dev/null @@ -1,494 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mariadb -// Service ID: 115 - -var _ resource.Resource = &MariadbResource{} -var _ resource.ResourceWithModifyPlan = &MariadbResource{} -var _ resource.ResourceWithImportState = &MariadbResource{} - -type MariadbResource struct { - client *core.UniversalClient -} - -type MariadbModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - AutoscaleConfiguration types.String `tfsdk:"autoscale_configuration"` - BackupConfiguration types.String `tfsdk:"backup_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - MariadbConfiguration types.String `tfsdk:"mariadb_configuration"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewMariadbResource() resource.Resource { - return &MariadbResource{} -} - -func (r *MariadbResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mariadb" -} - -func (r *MariadbResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true}, - "autoscale_configuration": schema.StringAttribute{Required: true}, - "backup_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "mariadb_configuration": schema.StringAttribute{Required: true}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MariadbResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *MariadbModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.AutoscaleConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "autoscale_configuration is required.") - return - } - if config.AutoscaleConfiguration.IsUnknown() { - return - } - if config.BackupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "backup_configuration is required.") - return - } - if config.BackupConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.MariadbConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "mariadb_configuration is required.") - return - } - if config.MariadbConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 877: resources_core.FormatString(config.StartupConfiguration), - 878: resources_core.FormatString(config.ClusterConfiguration), - 879: resources_core.FormatString(config.AccessConfiguration), - 880: resources_core.FormatString(config.MariadbConfiguration), - 881: resources_core.FormatString(config.BackupConfiguration), - 882: resources_core.FormatString(config.AutoscaleConfiguration), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 115, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *MariadbResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.AutoscaleConfiguration.IsNull() || data.AutoscaleConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "autoscale_configuration is required.") - return - } - if data.BackupConfiguration.IsNull() || data.BackupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "backup_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.MariadbConfiguration.IsNull() || data.MariadbConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "mariadb_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 115, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 877: resources_core.FormatString(data.StartupConfiguration), - 878: resources_core.FormatString(data.ClusterConfiguration), - 879: resources_core.FormatString(data.AccessConfiguration), - 880: resources_core.FormatString(data.MariadbConfiguration), - 881: resources_core.FormatString(data.BackupConfiguration), - 882: resources_core.FormatString(data.AutoscaleConfiguration), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 115, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 115, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "mariadbConfiguration", Field: "MariadbConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 115, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "mariadbConfiguration", Field: "MariadbConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *MariadbResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MariadbModel - var state MariadbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessConfiguration.IsNull() != state.AccessConfiguration.IsNull() || plan.AccessConfiguration.IsUnknown() != state.AccessConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MariadbConfiguration.IsNull() != state.MariadbConfiguration.IsNull() || plan.MariadbConfiguration.IsUnknown() != state.MariadbConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MariadbConfiguration.IsNull() && !plan.MariadbConfiguration.IsUnknown() && !state.MariadbConfiguration.IsNull() && !state.MariadbConfiguration.IsUnknown() { - if !strings.EqualFold(plan.MariadbConfiguration.ValueString(), state.MariadbConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.BackupConfiguration.IsNull() != state.BackupConfiguration.IsNull() || plan.BackupConfiguration.IsUnknown() != state.BackupConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.BackupConfiguration.IsNull() && !plan.BackupConfiguration.IsUnknown() && !state.BackupConfiguration.IsNull() && !state.BackupConfiguration.IsUnknown() { - if !strings.EqualFold(plan.BackupConfiguration.ValueString(), state.BackupConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoscaleConfiguration.IsNull() != state.AutoscaleConfiguration.IsNull() || plan.AutoscaleConfiguration.IsUnknown() != state.AutoscaleConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoscaleConfiguration.IsNull() && !plan.AutoscaleConfiguration.IsUnknown() && !state.AutoscaleConfiguration.IsNull() && !state.AutoscaleConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AutoscaleConfiguration.ValueString(), state.AutoscaleConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 883: resources_core.FormatString(plan.ClusterConfiguration), - 884: resources_core.FormatString(plan.AccessConfiguration), - 885: resources_core.FormatString(plan.MariadbConfiguration), - 886: resources_core.FormatString(plan.BackupConfiguration), - 887: resources_core.FormatString(plan.AutoscaleConfiguration), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 115, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "mariadbConfiguration", Field: "MariadbConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MariadbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *MariadbResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *MariadbResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/115_mariadb_user_resource.go b/generated/test/go/115_mariadb_user_resource.go deleted file mode 100644 index 26f6858..0000000 --- a/generated/test/go/115_mariadb_user_resource.go +++ /dev/null @@ -1,375 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mariadb -// Subresource: user - -var _ resource.Resource = &MariadbUserResource{} - -// MariadbUserResource manages a subresource via operations. -type MariadbUserResource struct { - client *core.UniversalClient -} - -type MariadbUserModel struct { - ID types.String `tfsdk:"id"` - MariadbID types.String `tfsdk:"mariadb_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessHosts types.String `tfsdk:"access_hosts"` - DbName types.String `tfsdk:"db_name"` - Password types.String `tfsdk:"password"` - Username types.String `tfsdk:"username"` -} - -func NewMariadbUserResource() resource.Resource { - return &MariadbUserResource{} -} - -func (r *MariadbUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mariadb_user" -} - -func (r *MariadbUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "mariadb_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_hosts": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("%"), MarkdownDescription: "Пример: `%` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "db_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Необходимо указать массив существующих баз Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "password": schema.StringAttribute{Required: true, MarkdownDescription: "Секрет будет записан в хранилище секретов и не будет отображаться публично Не изменяется после создания. Изменение требует пересоздания.", Sensitive: true, PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "username": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("user"), MarkdownDescription: "Пример: `myusername` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MariadbUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan MariadbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.Password.IsNull() || plan.Password.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "password is required.") - return - } - - instanceUID := strings.TrimSpace(plan.MariadbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "dbName": resources_core.FormatString(plan.DbName), - "password": resources_core.FormatString(plan.Password), - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "accessHosts", - "dbName", - "password", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "password": resources_core.FormatString(plan.Password), - "dbName": resources_core.FormatString(plan.DbName), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MariadbUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MariadbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MariadbUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MariadbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state MariadbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.MariadbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "dbName": resources_core.FormatString(plan.DbName), - "password": resources_core.FormatString(plan.Password), - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MariadbUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MariadbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.MariadbID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(state.AccessHosts), - "dbName": resources_core.FormatString(state.DbName), - "password": resources_core.FormatString(state.Password), - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "accessHosts", - "dbName", - "password", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *MariadbUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/116_kafka_resource.go b/generated/test/go/116_kafka_resource.go deleted file mode 100644 index 5c1f42a..0000000 --- a/generated/test/go/116_kafka_resource.go +++ /dev/null @@ -1,500 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Service ID: 116 - -var _ resource.Resource = &KafkaResource{} -var _ resource.ResourceWithModifyPlan = &KafkaResource{} -var _ resource.ResourceWithImportState = &KafkaResource{} - -type KafkaResource struct { - client *core.UniversalClient -} - -type KafkaModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewKafkaResource() resource.Resource { - return &KafkaResource{} -} - -func (r *KafkaResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka" -} - -func (r *KafkaResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`"}, - "resource_c_p_u": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2000`"}, - "resource_disk": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `20`"}, - "resource_instances": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2`"}, - "resource_memory": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *KafkaModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceCPU.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if config.ResourceCPU.IsUnknown() { - return - } - if config.ResourceDisk.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if config.ResourceDisk.IsUnknown() { - return - } - if config.ResourceInstances.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if config.ResourceInstances.IsUnknown() { - return - } - if config.ResourceMemory.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if config.ResourceMemory.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 461: resources_core.FormatInt64(config.ResourceInstances), - 462: resources_core.FormatInt64(config.ResourceMemory), - 463: resources_core.FormatInt64(config.ResourceCPU), - 464: resources_core.FormatInt64(config.ResourceDisk), - 465: resources_core.FormatBool(config.NeedExternalAddressMaster), - 466: resources_core.FormatString(config.IpSpaceNameMaster), - 469: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 116, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *KafkaResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceCPU.IsNull() || data.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if data.ResourceDisk.IsNull() || data.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if data.ResourceInstances.IsNull() || data.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if data.ResourceMemory.IsNull() || data.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 116, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 461: resources_core.FormatInt64(data.ResourceInstances), - 462: resources_core.FormatInt64(data.ResourceMemory), - 463: resources_core.FormatInt64(data.ResourceCPU), - 464: resources_core.FormatInt64(data.ResourceDisk), - 465: resources_core.FormatBool(data.NeedExternalAddressMaster), - 466: resources_core.FormatString(data.IpSpaceNameMaster), - 469: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 116, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 116, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 116, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *KafkaResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaModel - var state KafkaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if !strings.EqualFold(plan.IpSpaceNameMaster.ValueString(), state.IpSpaceNameMaster.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 501: resources_core.FormatInt64(plan.ResourceInstances), - 502: resources_core.FormatInt64(plan.ResourceMemory), - 503: resources_core.FormatInt64(plan.ResourceCPU), - 504: resources_core.FormatInt64(plan.ResourceDisk), - 505: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 506: resources_core.FormatString(plan.IpSpaceNameMaster), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 116, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *KafkaResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *KafkaResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/116_kafka_topic_resource.go b/generated/test/go/116_kafka_topic_resource.go deleted file mode 100644 index a1f3041..0000000 --- a/generated/test/go/116_kafka_topic_resource.go +++ /dev/null @@ -1,368 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Subresource: topic - -var _ resource.Resource = &KafkaTopicResource{} - -// KafkaTopicResource manages a subresource via operations. -type KafkaTopicResource struct { - client *core.UniversalClient -} - -type KafkaTopicModel struct { - ID types.String `tfsdk:"id"` - KafkaID types.String `tfsdk:"kafka_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - NameTopic types.String `tfsdk:"name_topic"` - Partitions types.Int64 `tfsdk:"partitions"` - Replicas types.Int64 `tfsdk:"replicas"` -} - -func NewKafkaTopicResource() resource.Resource { - return &KafkaTopicResource{} -} - -func (r *KafkaTopicResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka_topic" -} - -func (r *KafkaTopicResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "kafka_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events` Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "partitions": schema.Int64Attribute{Required: true, MarkdownDescription: "Число партиций можно увеличить, но уменьшить их нельзя."}, - "replicas": schema.Int64Attribute{Required: true, MarkdownDescription: "Количество реплик не может привышать количество реплик брокера"}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaTopicResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan KafkaTopicModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.NameTopic.IsNull() || plan.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if plan.Partitions.IsNull() || plan.Partitions.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "partitions is required.") - return - } - if plan.Replicas.IsNull() || plan.Replicas.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "replicas is required.") - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - } - identityCodes := []string{ - "nameTopic", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("topic", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "partitions": resources_core.FormatInt64(plan.Partitions), - "replicas": resources_core.FormatInt64(plan.Replicas), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_topic", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_topic", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaTopicResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaTopicResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaTopicModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_topic" == "" { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "partitions": resources_core.FormatInt64(plan.Partitions), - "replicas": resources_core.FormatInt64(plan.Replicas), - }) - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_topic", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "topic", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaTopicResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaTopicModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_topic" == "" { - return - } - - instanceUID := strings.TrimSpace(state.KafkaID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "nameTopic": resources_core.FormatString(state.NameTopic), - } - identityCodes := []string{ - "nameTopic", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("topic", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(state.NameTopic), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_topic", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *KafkaTopicResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/116_kafka_user_resource.go b/generated/test/go/116_kafka_user_resource.go deleted file mode 100644 index b0d2933..0000000 --- a/generated/test/go/116_kafka_user_resource.go +++ /dev/null @@ -1,384 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: kafka -// Subresource: user - -var _ resource.Resource = &KafkaUserResource{} - -// KafkaUserResource manages a subresource via operations. -type KafkaUserResource struct { - client *core.UniversalClient -} - -type KafkaUserModel struct { - ID types.String `tfsdk:"id"` - KafkaID types.String `tfsdk:"kafka_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessHosts types.String `tfsdk:"access_hosts"` - Group types.String `tfsdk:"group"` - NameTopic types.String `tfsdk:"name_topic"` - Operations types.String `tfsdk:"operations"` - Username types.String `tfsdk:"username"` -} - -func NewKafkaUserResource() resource.Resource { - return &KafkaUserResource{} -} - -func (r *KafkaUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_kafka_user" -} - -func (r *KafkaUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "kafka_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_hosts": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `192.168.1.0/24` или `*`"}, - "group": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `order-consumers` или `*`"}, - "name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`"}, - "operations": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `Create, Describe, Read, Write`"}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `username-admin` Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *KafkaUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan KafkaUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.AccessHosts.IsNull() || plan.AccessHosts.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_hosts is required.") - return - } - if plan.Group.IsNull() || plan.Group.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "group is required.") - return - } - if plan.NameTopic.IsNull() || plan.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if plan.Operations.IsNull() || plan.Operations.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "operations is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "nameTopic": resources_core.FormatString(plan.NameTopic), - "operations": resources_core.FormatString(plan.Operations), - "group": resources_core.FormatString(plan.Group), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *KafkaUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan KafkaUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_user" == "" { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.KafkaID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "nameTopic": resources_core.FormatString(plan.NameTopic), - "operations": resources_core.FormatString(plan.Operations), - "group": resources_core.FormatString(plan.Group), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "username": resources_core.FormatString(plan.Username), - }) - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_user", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *KafkaUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state KafkaUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.KafkaID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *KafkaUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/117_nifi_resource.go b/generated/test/go/117_nifi_resource.go deleted file mode 100644 index afe981b..0000000 --- a/generated/test/go/117_nifi_resource.go +++ /dev/null @@ -1,528 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nifi -// Service ID: 117 - -var _ resource.Resource = &NifiResource{} -var _ resource.ResourceWithModifyPlan = &NifiResource{} -var _ resource.ResourceWithImportState = &NifiResource{} - -type NifiResource struct { - client *core.UniversalClient -} - -type NifiModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - KafkaUid types.String `tfsdk:"kafka_uid"` - NameTopic types.String `tfsdk:"name_topic"` - Partitions types.Int64 `tfsdk:"partitions"` - Replicas types.Int64 `tfsdk:"replicas"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNifiResource() resource.Resource { - return &NifiResource{} -} - -func (r *NifiResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nifi" -} - -func (r *NifiResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "kafka_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "Выбрать кластер из списка Не изменяется после создания."}, - "name_topic": schema.StringAttribute{Required: true, MarkdownDescription: "Пример: `orders-events` Не изменяется после создания."}, - "partitions": schema.Int64Attribute{Required: true, MarkdownDescription: "Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50`"}, - "replicas": schema.Int64Attribute{Required: true, MarkdownDescription: "Количество партиций ≤ (число брокеров). Пример `2`"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NifiResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NifiModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.KafkaUid.ValueString(), state.KafkaUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить kafka_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NameTopic.IsNull() && !plan.NameTopic.IsUnknown() && !state.NameTopic.IsNull() && !state.NameTopic.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.NameTopic.ValueString(), state.NameTopic.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить name_topic", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.KafkaUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if config.KafkaUid.IsUnknown() { - return - } - if config.NameTopic.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if config.NameTopic.IsUnknown() { - return - } - if config.Partitions.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "partitions is required.") - return - } - if config.Partitions.IsUnknown() { - return - } - if config.Replicas.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "replicas is required.") - return - } - if config.Replicas.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.KafkaUid.IsNull() && !config.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, config.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != config.KafkaUid.ValueString() { - config.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - params := map[int]string{ - 471: resources_core.FormatString(config.KafkaUid), - 472: resources_core.FormatInt64(config.Partitions), - 473: resources_core.FormatInt64(config.Replicas), - 474: resources_core.FormatString(config.NameTopic), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 117, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NifiResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.KafkaUid.IsNull() || data.KafkaUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if data.NameTopic.IsNull() || data.NameTopic.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "name_topic is required.") - return - } - if data.Partitions.IsNull() || data.Partitions.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "partitions is required.") - return - } - if data.Replicas.IsNull() || data.Replicas.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "replicas is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalKafkaUid := data.KafkaUid - if !data.KafkaUid.IsNull() && !data.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, data.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedKafkaUid != "" && resolvedKafkaUid != data.KafkaUid.ValueString() { - data.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 117, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 471: resources_core.FormatString(data.KafkaUid), - 472: resources_core.FormatInt64(data.Partitions), - 473: resources_core.FormatInt64(data.Replicas), - 474: resources_core.FormatString(data.NameTopic), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 117, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 117, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "nameTopic", Field: "NameTopic", Type: "string"}, - {Code: "partitions", Field: "Partitions", Type: "int64"}, - {Code: "replicas", Field: "Replicas", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalKafkaUid.IsNull() && !originalKafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - if strings.EqualFold(state.KafkaUid.ValueString(), originalKafkaUid.ValueString()) { - state.KafkaUid = originalKafkaUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NifiResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 117, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "nameTopic", Field: "NameTopic", Type: "string"}, - {Code: "partitions", Field: "Partitions", Type: "int64"}, - {Code: "replicas", Field: "Replicas", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, newState.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != newState.KafkaUid.ValueString() { - newState.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() && !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() { - if strings.EqualFold(newState.KafkaUid.ValueString(), state.KafkaUid.ValueString()) { - newState.KafkaUid = state.KafkaUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NifiResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NifiModel - var state NifiModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.Partitions.IsNull() != state.Partitions.IsNull() || plan.Partitions.IsUnknown() != state.Partitions.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.Partitions.IsNull() && !plan.Partitions.IsUnknown() && !state.Partitions.IsNull() && !state.Partitions.IsUnknown() { - if plan.Partitions.ValueInt64() != state.Partitions.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.Replicas.IsNull() != state.Replicas.IsNull() || plan.Replicas.IsUnknown() != state.Replicas.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.Replicas.IsNull() && !plan.Replicas.IsUnknown() && !state.Replicas.IsNull() && !state.Replicas.IsUnknown() { - if plan.Replicas.ValueInt64() != state.Replicas.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 477: resources_core.FormatInt64(plan.Partitions), - 478: resources_core.FormatInt64(plan.Replicas), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 117, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "nameTopic", Field: "NameTopic", Type: "string"}, - {Code: "partitions", Field: "Partitions", Type: "int64"}, - {Code: "replicas", Field: "Replicas", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - if strings.EqualFold(state.KafkaUid.ValueString(), plan.KafkaUid.ValueString()) { - state.KafkaUid = plan.KafkaUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NifiResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NifiModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NifiResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NifiResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/119_akhq_resource.go b/generated/test/go/119_akhq_resource.go deleted file mode 100644 index 2aadab6..0000000 --- a/generated/test/go/119_akhq_resource.go +++ /dev/null @@ -1,549 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: akhq -// Service ID: 119 - -var _ resource.Resource = &AkhqResource{} -var _ resource.ResourceWithModifyPlan = &AkhqResource{} -var _ resource.ResourceWithImportState = &AkhqResource{} - -type AkhqResource struct { - client *core.UniversalClient -} - -type AkhqModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - KafkaUid types.String `tfsdk:"kafka_uid"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewAkhqResource() resource.Resource { - return &AkhqResource{} -} - -func (r *AkhqResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_akhq" -} - -func (r *AkhqResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "kafka_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "Выбрать кластер из списка"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Пример: `1000` Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Пример: `1024` Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *AkhqResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *AkhqModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.Domain.IsUnknown() { - return - } - if config.KafkaUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if config.KafkaUid.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.KafkaUid.IsNull() && !config.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, config.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != config.KafkaUid.ValueString() { - config.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - params := map[int]string{ - 550: resources_core.FormatString(config.ResourceRealm), - 551: resources_core.FormatInt64(config.ResourceMemory), - 552: resources_core.FormatInt64(config.ResourceCPU), - 553: resources_core.FormatString(config.Domain), - 554: resources_core.FormatInt64(config.ResourceInstances), - 555: resources_core.FormatString(config.KafkaUid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 119, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *AkhqResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.KafkaUid.IsNull() || data.KafkaUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "kafka_uid is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalKafkaUid := data.KafkaUid - if !data.KafkaUid.IsNull() && !data.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, data.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedKafkaUid != "" && resolvedKafkaUid != data.KafkaUid.ValueString() { - data.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 119, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 550: resources_core.FormatString(data.ResourceRealm), - 551: resources_core.FormatInt64(data.ResourceMemory), - 552: resources_core.FormatInt64(data.ResourceCPU), - 553: resources_core.FormatString(data.Domain), - 554: resources_core.FormatInt64(data.ResourceInstances), - 555: resources_core.FormatString(data.KafkaUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 119, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 119, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalKafkaUid.IsNull() && !originalKafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - if strings.EqualFold(state.KafkaUid.ValueString(), originalKafkaUid.ValueString()) { - state.KafkaUid = originalKafkaUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *AkhqResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 119, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, newState.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != newState.KafkaUid.ValueString() { - newState.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() && !newState.KafkaUid.IsNull() && !newState.KafkaUid.IsUnknown() { - if strings.EqualFold(newState.KafkaUid.ValueString(), state.KafkaUid.ValueString()) { - newState.KafkaUid = state.KafkaUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *AkhqResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan AkhqModel - var state AkhqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.KafkaUid.IsNull() != state.KafkaUid.IsNull() || plan.KafkaUid.IsUnknown() != state.KafkaUid.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - if !strings.EqualFold(plan.KafkaUid.ValueString(), state.KafkaUid.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 565: resources_core.FormatString(plan.KafkaUid), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 119, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "kafkaUid", Field: "KafkaUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - resolvedKafkaUid, err := r.client.ResolveRefSvcParamValue(ctx, 116, state.KafkaUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve kafka_uid", err.Error()) - } else if resolvedKafkaUid != "" && resolvedKafkaUid != state.KafkaUid.ValueString() { - state.KafkaUid = types.StringValue(resolvedKafkaUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.KafkaUid.IsNull() && !plan.KafkaUid.IsUnknown() && !state.KafkaUid.IsNull() && !state.KafkaUid.IsUnknown() { - if strings.EqualFold(state.KafkaUid.ValueString(), plan.KafkaUid.ValueString()) { - state.KafkaUid = plan.KafkaUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *AkhqResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state AkhqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *AkhqResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *AkhqResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/120_clickhouse_database_resource.go b/generated/test/go/120_clickhouse_database_resource.go deleted file mode 100644 index acefa96..0000000 --- a/generated/test/go/120_clickhouse_database_resource.go +++ /dev/null @@ -1,347 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Subresource: database - -var _ resource.Resource = &ClickhouseDatabaseResource{} - -// ClickhouseDatabaseResource manages a subresource via operations. -type ClickhouseDatabaseResource struct { - client *core.UniversalClient -} - -type ClickhouseDatabaseModel struct { - ID types.String `tfsdk:"id"` - ClickhouseID types.String `tfsdk:"clickhouse_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DbName types.String `tfsdk:"db_name"` -} - -func NewClickhouseDatabaseResource() resource.Resource { - return &ClickhouseDatabaseResource{} -} - -func (r *ClickhouseDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse_database" -} - -func (r *ClickhouseDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "clickhouse_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "db_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("db01"), MarkdownDescription: "Пример: `db01` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan ClickhouseDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - } - identityCodes := []string{ - "dbName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_database" == "" { - return - } - - instanceUID := strings.TrimSpace(state.ClickhouseID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "dbName": resources_core.FormatString(state.DbName), - } - identityCodes := []string{ - "dbName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "dbName": resources_core.FormatString(state.DbName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_database", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *ClickhouseDatabaseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/120_clickhouse_resource.go b/generated/test/go/120_clickhouse_resource.go deleted file mode 100644 index ce9c514..0000000 --- a/generated/test/go/120_clickhouse_resource.go +++ /dev/null @@ -1,539 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Service ID: 120 - -var _ resource.Resource = &ClickhouseResource{} -var _ resource.ResourceWithModifyPlan = &ClickhouseResource{} -var _ resource.ResourceWithImportState = &ClickhouseResource{} - -type ClickhouseResource struct { - client *core.UniversalClient -} - -type ClickhouseModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - AutoscaleConfiguration types.String `tfsdk:"autoscale_configuration"` - BackupConfiguration types.String `tfsdk:"backup_configuration"` - ClickhouseConfiguration types.String `tfsdk:"clickhouse_configuration"` - ClickhouseFilesConfiguration types.String `tfsdk:"clickhouse_files_configuration"` - ClickhouseKeeperConfiguration types.String `tfsdk:"clickhouse_keeper_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewClickhouseResource() resource.Resource { - return &ClickhouseResource{} -} - -func (r *ClickhouseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse" -} - -func (r *ClickhouseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true}, - "autoscale_configuration": schema.StringAttribute{Required: true}, - "backup_configuration": schema.StringAttribute{Required: true}, - "clickhouse_configuration": schema.StringAttribute{Required: true}, - "clickhouse_files_configuration": schema.StringAttribute{Optional: true, MarkdownDescription: "Формат:
- path: somethings3.xml
xmlConfig: '<clickhouse>......</clickhouse>'"}, - "clickhouse_keeper_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *ClickhouseModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.AutoscaleConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "autoscale_configuration is required.") - return - } - if config.AutoscaleConfiguration.IsUnknown() { - return - } - if config.BackupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "backup_configuration is required.") - return - } - if config.BackupConfiguration.IsUnknown() { - return - } - if config.ClickhouseConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "clickhouse_configuration is required.") - return - } - if config.ClickhouseConfiguration.IsUnknown() { - return - } - if config.ClickhouseKeeperConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "clickhouse_keeper_configuration is required.") - return - } - if config.ClickhouseKeeperConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 837: resources_core.FormatString(config.StartupConfiguration), - 838: resources_core.FormatString(config.ClusterConfiguration), - 839: resources_core.FormatString(config.AccessConfiguration), - 840: resources_core.FormatString(config.ClickhouseKeeperConfiguration), - 841: resources_core.FormatString(config.ClickhouseConfiguration), - 842: resources_core.FormatString(config.BackupConfiguration), - 843: resources_core.FormatString(config.AutoscaleConfiguration), - 851: resources_core.FormatString(config.ClickhouseFilesConfiguration), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 120, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *ClickhouseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.AutoscaleConfiguration.IsNull() || data.AutoscaleConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "autoscale_configuration is required.") - return - } - if data.BackupConfiguration.IsNull() || data.BackupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "backup_configuration is required.") - return - } - if data.ClickhouseConfiguration.IsNull() || data.ClickhouseConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "clickhouse_configuration is required.") - return - } - if data.ClickhouseKeeperConfiguration.IsNull() || data.ClickhouseKeeperConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "clickhouse_keeper_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 120, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 837: resources_core.FormatString(data.StartupConfiguration), - 838: resources_core.FormatString(data.ClusterConfiguration), - 839: resources_core.FormatString(data.AccessConfiguration), - 840: resources_core.FormatString(data.ClickhouseKeeperConfiguration), - 841: resources_core.FormatString(data.ClickhouseConfiguration), - 842: resources_core.FormatString(data.BackupConfiguration), - 843: resources_core.FormatString(data.AutoscaleConfiguration), - 851: resources_core.FormatString(data.ClickhouseFilesConfiguration), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 120, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 120, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clickhouseConfiguration", Field: "ClickhouseConfiguration", Type: "string"}, - {Code: "clickhouseFilesConfiguration", Field: "ClickhouseFilesConfiguration", Type: "string"}, - {Code: "clickhouseKeeperConfiguration", Field: "ClickhouseKeeperConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 120, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clickhouseConfiguration", Field: "ClickhouseConfiguration", Type: "string"}, - {Code: "clickhouseFilesConfiguration", Field: "ClickhouseFilesConfiguration", Type: "string"}, - {Code: "clickhouseKeeperConfiguration", Field: "ClickhouseKeeperConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *ClickhouseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseModel - var state ClickhouseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ClickhouseKeeperConfiguration.IsNull() != state.ClickhouseKeeperConfiguration.IsNull() || plan.ClickhouseKeeperConfiguration.IsUnknown() != state.ClickhouseKeeperConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClickhouseKeeperConfiguration.IsNull() && !plan.ClickhouseKeeperConfiguration.IsUnknown() && !state.ClickhouseKeeperConfiguration.IsNull() && !state.ClickhouseKeeperConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClickhouseKeeperConfiguration.ValueString(), state.ClickhouseKeeperConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessConfiguration.IsNull() != state.AccessConfiguration.IsNull() || plan.AccessConfiguration.IsUnknown() != state.AccessConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ClickhouseConfiguration.IsNull() != state.ClickhouseConfiguration.IsNull() || plan.ClickhouseConfiguration.IsUnknown() != state.ClickhouseConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClickhouseConfiguration.IsNull() && !plan.ClickhouseConfiguration.IsUnknown() && !state.ClickhouseConfiguration.IsNull() && !state.ClickhouseConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClickhouseConfiguration.ValueString(), state.ClickhouseConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.BackupConfiguration.IsNull() != state.BackupConfiguration.IsNull() || plan.BackupConfiguration.IsUnknown() != state.BackupConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.BackupConfiguration.IsNull() && !plan.BackupConfiguration.IsUnknown() && !state.BackupConfiguration.IsNull() && !state.BackupConfiguration.IsUnknown() { - if !strings.EqualFold(plan.BackupConfiguration.ValueString(), state.BackupConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoscaleConfiguration.IsNull() != state.AutoscaleConfiguration.IsNull() || plan.AutoscaleConfiguration.IsUnknown() != state.AutoscaleConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoscaleConfiguration.IsNull() && !plan.AutoscaleConfiguration.IsUnknown() && !state.AutoscaleConfiguration.IsNull() && !state.AutoscaleConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AutoscaleConfiguration.ValueString(), state.AutoscaleConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ClickhouseFilesConfiguration.IsNull() != state.ClickhouseFilesConfiguration.IsNull() || plan.ClickhouseFilesConfiguration.IsUnknown() != state.ClickhouseFilesConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClickhouseFilesConfiguration.IsNull() && !plan.ClickhouseFilesConfiguration.IsUnknown() && !state.ClickhouseFilesConfiguration.IsNull() && !state.ClickhouseFilesConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClickhouseFilesConfiguration.ValueString(), state.ClickhouseFilesConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 844: resources_core.FormatString(plan.ClusterConfiguration), - 845: resources_core.FormatString(plan.ClickhouseKeeperConfiguration), - 846: resources_core.FormatString(plan.AccessConfiguration), - 847: resources_core.FormatString(plan.ClickhouseConfiguration), - 848: resources_core.FormatString(plan.BackupConfiguration), - 849: resources_core.FormatString(plan.AutoscaleConfiguration), - 850: resources_core.FormatString(plan.ClickhouseFilesConfiguration), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 120, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clickhouseConfiguration", Field: "ClickhouseConfiguration", Type: "string"}, - {Code: "clickhouseFilesConfiguration", Field: "ClickhouseFilesConfiguration", Type: "string"}, - {Code: "clickhouseKeeperConfiguration", Field: "ClickhouseKeeperConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *ClickhouseResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *ClickhouseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/120_clickhouse_user_resource.go b/generated/test/go/120_clickhouse_user_resource.go deleted file mode 100644 index b797482..0000000 --- a/generated/test/go/120_clickhouse_user_resource.go +++ /dev/null @@ -1,363 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: clickhouse -// Subresource: user - -var _ resource.Resource = &ClickhouseUserResource{} - -// ClickhouseUserResource manages a subresource via operations. -type ClickhouseUserResource struct { - client *core.UniversalClient -} - -type ClickhouseUserModel struct { - ID types.String `tfsdk:"id"` - ClickhouseID types.String `tfsdk:"clickhouse_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessHosts types.String `tfsdk:"access_hosts"` - DbName types.String `tfsdk:"db_name"` - Username types.String `tfsdk:"username"` -} - -func NewClickhouseUserResource() resource.Resource { - return &ClickhouseUserResource{} -} - -func (r *ClickhouseUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_clickhouse_user" -} - -func (r *ClickhouseUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "clickhouse_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_hosts": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("::/0"), MarkdownDescription: "Пример: `::/0` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "db_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "username": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("myusername"), MarkdownDescription: "Пример: `myusername` Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ClickhouseUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan ClickhouseUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "dbName": resources_core.FormatString(plan.DbName), - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "accessHosts", - "dbName", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "dbName": resources_core.FormatString(plan.DbName), - "accessHosts": resources_core.FormatString(plan.AccessHosts), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ClickhouseUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ClickhouseUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.ClickhouseID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(plan.AccessHosts), - "dbName": resources_core.FormatString(plan.DbName), - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *ClickhouseUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ClickhouseUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.ClickhouseID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "accessHosts": resources_core.FormatString(state.AccessHosts), - "dbName": resources_core.FormatString(state.DbName), - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "accessHosts", - "dbName", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *ClickhouseUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/12_s3_resource.go b/generated/test/go/12_s3_resource.go deleted file mode 100644 index af49186..0000000 --- a/generated/test/go/12_s3_resource.go +++ /dev/null @@ -1,426 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3 -// Service ID: 12 - -var _ resource.Resource = &S3Resource{} -var _ resource.ResourceWithModifyPlan = &S3Resource{} -var _ resource.ResourceWithImportState = &S3Resource{} - -type S3Resource struct { - client *core.UniversalClient -} - -type S3Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DisplayName types.String `tfsdk:"display_name"` - MaxBucketsPerUser types.Int64 `tfsdk:"max_buckets_per_user"` - MaxObjectsPerBucket types.Int64 `tfsdk:"max_objects_per_bucket"` - MaxSizeGbPerUser types.Int64 `tfsdk:"max_size_gb_per_user"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewS3Resource() resource.Resource { - return &S3Resource{} -} - -func (r *S3Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3" -} - -func (r *S3Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "display_name": schema.StringAttribute{Required: true, MarkdownDescription: "Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента Не изменяется после создания."}, - "max_buckets_per_user": schema.Int64Attribute{Optional: true, MarkdownDescription: "Квота на пользователя. Количество бакетов пользователя. Передаём руками"}, - "max_objects_per_bucket": schema.Int64Attribute{Optional: true, MarkdownDescription: "Квота на бакет. Кол-во объектов. Передаём руками"}, - "max_size_gb_per_user": schema.Int64Attribute{Optional: true, MarkdownDescription: "maxSizeGb. Передаём руками"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *S3Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.DisplayName.IsNull() && !plan.DisplayName.IsUnknown() && !state.DisplayName.IsNull() && !state.DisplayName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.DisplayName.ValueString(), state.DisplayName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить display_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.DisplayName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "display_name is required.") - return - } - if config.DisplayName.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 163: resources_core.FormatString(config.ResourceRealm), - 320: resources_core.FormatString(config.DisplayName), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 12, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *S3Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.DisplayName.IsNull() || data.DisplayName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "display_name is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 12, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 163: resources_core.FormatString(data.ResourceRealm), - 320: resources_core.FormatString(data.DisplayName), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 12, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 12, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 12, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *S3Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3Model - var state S3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.MaxSizeGbPerUser.IsNull() != state.MaxSizeGbPerUser.IsNull() || plan.MaxSizeGbPerUser.IsUnknown() != state.MaxSizeGbPerUser.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxSizeGbPerUser.IsNull() && !plan.MaxSizeGbPerUser.IsUnknown() && !state.MaxSizeGbPerUser.IsNull() && !state.MaxSizeGbPerUser.IsUnknown() { - if plan.MaxSizeGbPerUser.ValueInt64() != state.MaxSizeGbPerUser.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MaxObjectsPerBucket.IsNull() != state.MaxObjectsPerBucket.IsNull() || plan.MaxObjectsPerBucket.IsUnknown() != state.MaxObjectsPerBucket.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxObjectsPerBucket.IsNull() && !plan.MaxObjectsPerBucket.IsUnknown() && !state.MaxObjectsPerBucket.IsNull() && !state.MaxObjectsPerBucket.IsUnknown() { - if plan.MaxObjectsPerBucket.ValueInt64() != state.MaxObjectsPerBucket.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MaxBucketsPerUser.IsNull() != state.MaxBucketsPerUser.IsNull() || plan.MaxBucketsPerUser.IsUnknown() != state.MaxBucketsPerUser.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MaxBucketsPerUser.IsNull() && !plan.MaxBucketsPerUser.IsUnknown() && !state.MaxBucketsPerUser.IsNull() && !state.MaxBucketsPerUser.IsUnknown() { - if plan.MaxBucketsPerUser.ValueInt64() != state.MaxBucketsPerUser.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 50: resources_core.FormatInt64(plan.MaxSizeGbPerUser), - 51: resources_core.FormatInt64(plan.MaxObjectsPerBucket), - 52: resources_core.FormatInt64(plan.MaxBucketsPerUser), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 12, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "displayName", Field: "DisplayName", Type: "string"}, - {Code: "maxBucketsPerUser", Field: "MaxBucketsPerUser", Type: "int64"}, - {Code: "maxObjectsPerBucket", Field: "MaxObjectsPerBucket", Type: "int64"}, - {Code: "maxSizeGbPerUser", Field: "MaxSizeGbPerUser", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *S3Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *S3Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/12_s3_sub_user_resource.go b/generated/test/go/12_s3_sub_user_resource.go deleted file mode 100644 index 54551ae..0000000 --- a/generated/test/go/12_s3_sub_user_resource.go +++ /dev/null @@ -1,362 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3 -// Subresource: sub_user - -var _ resource.Resource = &S3SubUserResource{} - -// S3SubUserResource manages a subresource via operations. -type S3SubUserResource struct { - client *core.UniversalClient -} - -type S3SubUserModel struct { - ID types.String `tfsdk:"id"` - S3ID types.String `tfsdk:"s3_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - SubUserAccess types.String `tfsdk:"sub_user_access"` - SubUserName types.String `tfsdk:"sub_user_name"` -} - -func NewS3SubUserResource() resource.Resource { - return &S3SubUserResource{} -} - -func (r *S3SubUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3_sub_user" -} - -func (r *S3SubUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "s3_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "sub_user_access": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "sub_user_name": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3SubUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan S3SubUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.SubUserAccess.IsNull() || plan.SubUserAccess.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "sub_user_access is required.") - return - } - if plan.SubUserName.IsNull() || plan.SubUserName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "sub_user_name is required.") - return - } - - instanceUID := strings.TrimSpace(plan.S3ID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - "subUserName": resources_core.FormatString(plan.SubUserName), - } - identityCodes := []string{ - "subUserAccess", - "subUserName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("sub_user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "subUserName": resources_core.FormatString(plan.SubUserName), - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_sub_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_sub_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *S3SubUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3SubUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3SubUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.S3ID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(plan.SubUserAccess), - "subUserName": resources_core.FormatString(plan.SubUserName), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "sub_user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *S3SubUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3SubUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_sub_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.S3ID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "subUserAccess": resources_core.FormatString(state.SubUserAccess), - "subUserName": resources_core.FormatString(state.SubUserName), - } - identityCodes := []string{ - "subUserAccess", - "subUserName", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("sub_user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "subUserName": resources_core.FormatString(state.SubUserName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_sub_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *S3SubUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/13_s3bucket_resource.go b/generated/test/go/13_s3bucket_resource.go deleted file mode 100644 index df9acbe..0000000 --- a/generated/test/go/13_s3bucket_resource.go +++ /dev/null @@ -1,473 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: s3bucket -// Service ID: 13 - -var _ resource.Resource = &S3bucketResource{} -var _ resource.ResourceWithModifyPlan = &S3bucketResource{} -var _ resource.ResourceWithImportState = &S3bucketResource{} - -type S3bucketResource struct { - client *core.UniversalClient -} - -type S3bucketModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - BucketName types.String `tfsdk:"bucket_name"` - CorsAll types.Bool `tfsdk:"cors_all"` - ListAll types.Bool `tfsdk:"list_all"` - MaxSize types.String `tfsdk:"max_size"` - Placement types.String `tfsdk:"placement"` - ReadAll types.Bool `tfsdk:"read_all"` - S3UserUid types.String `tfsdk:"s3_user_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewS3bucketResource() resource.Resource { - return &S3bucketResource{} -} - -func (r *S3bucketResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_s3bucket" -} - -func (r *S3bucketResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "bucket_name": schema.StringAttribute{Required: true, MarkdownDescription: "Имя бакета s3 Не изменяется после создания."}, - "cors_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS Не изменяется после создания."}, - "list_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. Не изменяется после создания."}, - "max_size": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("-1"), MarkdownDescription: "Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes Не изменяется после создания."}, - "placement": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("HOT"), MarkdownDescription: "Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения Не изменяется после создания."}, - "read_all": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. Не изменяется после создания."}, - "s3_user_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UID Корневой услуги S3. На основе него будет создан бакет. Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *S3bucketResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *S3bucketModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.BucketName.IsNull() && !plan.BucketName.IsUnknown() && !state.BucketName.IsNull() && !state.BucketName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.BucketName.ValueString(), state.BucketName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить bucket_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.CorsAll.IsNull() && !plan.CorsAll.IsUnknown() && !state.CorsAll.IsNull() && !state.CorsAll.IsUnknown() { - if plan.CorsAll.ValueBool() != state.CorsAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить cors_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ListAll.IsNull() && !plan.ListAll.IsUnknown() && !state.ListAll.IsNull() && !state.ListAll.IsUnknown() { - if plan.ListAll.ValueBool() != state.ListAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить list_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MaxSize.IsNull() && !plan.MaxSize.IsUnknown() && !state.MaxSize.IsNull() && !state.MaxSize.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.MaxSize.ValueString(), state.MaxSize.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить max_size", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Placement.IsNull() && !plan.Placement.IsUnknown() && !state.Placement.IsNull() && !state.Placement.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Placement.ValueString(), state.Placement.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить placement", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ReadAll.IsNull() && !plan.ReadAll.IsUnknown() && !state.ReadAll.IsNull() && !state.ReadAll.IsUnknown() { - if plan.ReadAll.ValueBool() != state.ReadAll.ValueBool() { - resp.Diagnostics.AddError("Нельзя изменить read_all", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3UserUid.IsNull() && !plan.S3UserUid.IsUnknown() && !state.S3UserUid.IsNull() && !state.S3UserUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.S3UserUid.ValueString(), state.S3UserUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить s3_user_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.BucketName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "bucket_name is required.") - return - } - if config.BucketName.IsUnknown() { - return - } - if config.S3UserUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "s3_user_uid is required.") - return - } - if config.S3UserUid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3UserUid.IsNull() && !config.S3UserUid.IsUnknown() { - resolvedS3UserUid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3UserUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_user_uid", err.Error()) - } else if resolvedS3UserUid != "" && resolvedS3UserUid != config.S3UserUid.ValueString() { - config.S3UserUid = types.StringValue(resolvedS3UserUid) - } - } - params := map[int]string{ - 124: resources_core.FormatString(config.S3UserUid), - 125: resources_core.FormatString(config.BucketName), - 126: resources_core.FormatString(config.MaxSize), - 127: resources_core.FormatBool(config.ReadAll), - 128: resources_core.FormatBool(config.ListAll), - 129: resources_core.FormatBool(config.CorsAll), - 130: resources_core.FormatString(config.Placement), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 13, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *S3bucketResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.BucketName.IsNull() || data.BucketName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "bucket_name is required.") - return - } - if data.S3UserUid.IsNull() || data.S3UserUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_user_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 13, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 124: resources_core.FormatString(data.S3UserUid), - 125: resources_core.FormatString(data.BucketName), - 126: resources_core.FormatString(data.MaxSize), - 127: resources_core.FormatBool(data.ReadAll), - 128: resources_core.FormatBool(data.ListAll), - 129: resources_core.FormatBool(data.CorsAll), - 130: resources_core.FormatString(data.Placement), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 13, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 13, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3bucketResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 13, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *S3bucketResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan S3bucketModel - var state S3bucketModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 13, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "bucketName", Field: "BucketName", Type: "string"}, - {Code: "corsAll", Field: "CorsAll", Type: "bool"}, - {Code: "listAll", Field: "ListAll", Type: "bool"}, - {Code: "maxSize", Field: "MaxSize", Type: "string"}, - {Code: "placement", Field: "Placement", Type: "string"}, - {Code: "readAll", Field: "ReadAll", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *S3bucketResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state S3bucketModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *S3bucketResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *S3bucketResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/149_valo_tenant_resource.go b/generated/test/go/149_valo_tenant_resource.go deleted file mode 100644 index e85fe67..0000000 --- a/generated/test/go/149_valo_tenant_resource.go +++ /dev/null @@ -1,423 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: valo_tenant -// Service ID: 149 - -var _ resource.Resource = &ValoTenantResource{} -var _ resource.ResourceWithModifyPlan = &ValoTenantResource{} -var _ resource.ResourceWithImportState = &ValoTenantResource{} - -type ValoTenantResource struct { - client *core.UniversalClient -} - -type ValoTenantModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Storage types.Int64 `tfsdk:"s3_storage"` - ValoOptions types.String `tfsdk:"valo_options"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewValoTenantResource() resource.Resource { - return &ValoTenantResource{} -} - -func (r *ValoTenantResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_valo_tenant" -} - -func (r *ValoTenantResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Будет добавлено в зону valo.ngcloud.ru Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "s3_storage": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10), MarkdownDescription: "Параметр указывается в `Gb`"}, - "valo_options": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{}")}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *ValoTenantResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *ValoTenantModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.Domain.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 655: resources_core.FormatString(config.ResourceRealm), - 656: resources_core.FormatString(config.Domain), - 657: resources_core.FormatString(config.ValoOptions), - 658: resources_core.FormatInt64(config.S3Storage), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 149, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *ValoTenantResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 149, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 655: resources_core.FormatString(data.ResourceRealm), - 656: resources_core.FormatString(data.Domain), - 657: resources_core.FormatString(data.ValoOptions), - 658: resources_core.FormatInt64(data.S3Storage), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 149, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 149, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ValoTenantResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 149, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *ValoTenantResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan ValoTenantModel - var state ValoTenantModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ValoOptions.IsNull() != state.ValoOptions.IsNull() || plan.ValoOptions.IsUnknown() != state.ValoOptions.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ValoOptions.IsNull() && !plan.ValoOptions.IsUnknown() && !state.ValoOptions.IsNull() && !state.ValoOptions.IsUnknown() { - if !strings.EqualFold(plan.ValoOptions.ValueString(), state.ValoOptions.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.S3Storage.IsNull() != state.S3Storage.IsNull() || plan.S3Storage.IsUnknown() != state.S3Storage.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.S3Storage.IsNull() && !plan.S3Storage.IsUnknown() && !state.S3Storage.IsNull() && !state.S3Storage.IsUnknown() { - if plan.S3Storage.ValueInt64() != state.S3Storage.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 659: resources_core.FormatString(plan.ValoOptions), - 660: resources_core.FormatInt64(plan.S3Storage), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 149, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "s3Storage", Field: "S3Storage", Type: "int64"}, - {Code: "valoOptions", Field: "ValoOptions", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *ValoTenantResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ValoTenantModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *ValoTenantResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *ValoTenantResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/150_k8s_sthutrval_cluster_resource.go b/generated/test/go/150_k8s_sthutrval_cluster_resource.go deleted file mode 100644 index b1ab187..0000000 --- a/generated/test/go/150_k8s_sthutrval_cluster_resource.go +++ /dev/null @@ -1,456 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_sthutrval_cluster -// Service ID: 150 - -var _ resource.Resource = &K8sSthutrvalClusterResource{} -var _ resource.ResourceWithModifyPlan = &K8sSthutrvalClusterResource{} -var _ resource.ResourceWithImportState = &K8sSthutrvalClusterResource{} - -type K8sSthutrvalClusterResource struct { - client *core.UniversalClient -} - -type K8sSthutrvalClusterModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - ControlPlaneConfiguration types.String `tfsdk:"control_plane_configuration"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - WorkerConfiguration types.String `tfsdk:"worker_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewK8sSthutrvalClusterResource() resource.Resource { - return &K8sSthutrvalClusterResource{} -} - -func (r *K8sSthutrvalClusterResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_sthutrval_cluster" -} - -func (r *K8sSthutrvalClusterResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "control_plane_configuration": schema.StringAttribute{Required: true}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "worker_configuration": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]")}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sSthutrvalClusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.ControlPlaneConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "control_plane_configuration is required.") - return - } - if config.ControlPlaneConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 750: resources_core.FormatString(config.StartupConfiguration), - 751: resources_core.FormatString(config.ControlPlaneConfiguration), - 752: resources_core.FormatString(config.WorkerConfiguration), - 753: resources_core.FormatString(config.AccessConfiguration), - 755: resources_core.FormatString(config.ClusterConfiguration), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 150, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *K8sSthutrvalClusterResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.ControlPlaneConfiguration.IsNull() || data.ControlPlaneConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "control_plane_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 150, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 750: resources_core.FormatString(data.StartupConfiguration), - 751: resources_core.FormatString(data.ControlPlaneConfiguration), - 752: resources_core.FormatString(data.WorkerConfiguration), - 753: resources_core.FormatString(data.AccessConfiguration), - 755: resources_core.FormatString(data.ClusterConfiguration), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 150, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 150, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "controlPlaneConfiguration", Field: "ControlPlaneConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - {Code: "workerConfiguration", Field: "WorkerConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 150, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "controlPlaneConfiguration", Field: "ControlPlaneConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - {Code: "workerConfiguration", Field: "WorkerConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *K8sSthutrvalClusterResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sSthutrvalClusterModel - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ControlPlaneConfiguration.IsNull() != state.ControlPlaneConfiguration.IsNull() || plan.ControlPlaneConfiguration.IsUnknown() != state.ControlPlaneConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ControlPlaneConfiguration.IsNull() && !plan.ControlPlaneConfiguration.IsUnknown() && !state.ControlPlaneConfiguration.IsNull() && !state.ControlPlaneConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ControlPlaneConfiguration.ValueString(), state.ControlPlaneConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.WorkerConfiguration.IsNull() != state.WorkerConfiguration.IsNull() || plan.WorkerConfiguration.IsUnknown() != state.WorkerConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.WorkerConfiguration.IsNull() && !plan.WorkerConfiguration.IsUnknown() && !state.WorkerConfiguration.IsNull() && !state.WorkerConfiguration.IsUnknown() { - if !strings.EqualFold(plan.WorkerConfiguration.ValueString(), state.WorkerConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessConfiguration.IsNull() != state.AccessConfiguration.IsNull() || plan.AccessConfiguration.IsUnknown() != state.AccessConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 756: resources_core.FormatString(plan.ClusterConfiguration), - 757: resources_core.FormatString(plan.ControlPlaneConfiguration), - 758: resources_core.FormatString(plan.WorkerConfiguration), - 759: resources_core.FormatString(plan.AccessConfiguration), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 150, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "controlPlaneConfiguration", Field: "ControlPlaneConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - {Code: "workerConfiguration", Field: "WorkerConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sSthutrvalClusterModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *K8sSthutrvalClusterResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *K8sSthutrvalClusterResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/150_k8s_sthutrval_cluster_user_resource.go b/generated/test/go/150_k8s_sthutrval_cluster_user_resource.go deleted file mode 100644 index 7dbdeb4..0000000 --- a/generated/test/go/150_k8s_sthutrval_cluster_user_resource.go +++ /dev/null @@ -1,347 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_sthutrval_cluster -// Subresource: user - -var _ resource.Resource = &K8sSthutrvalClusterUserResource{} - -// K8sSthutrvalClusterUserResource manages a subresource via operations. -type K8sSthutrvalClusterUserResource struct { - client *core.UniversalClient -} - -type K8sSthutrvalClusterUserModel struct { - ID types.String `tfsdk:"id"` - K8sSthutrvalClusterID types.String `tfsdk:"k8s_sthutrval_cluster_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Admins types.String `tfsdk:"admins"` -} - -func NewK8sSthutrvalClusterUserResource() resource.Resource { - return &K8sSthutrvalClusterUserResource{} -} - -func (r *K8sSthutrvalClusterUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_sthutrval_cluster_user" -} - -func (r *K8sSthutrvalClusterUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "k8s_sthutrval_cluster_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "admins": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sSthutrvalClusterUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan K8sSthutrvalClusterUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "admins": resources_core.FormatString(plan.Admins), - } - identityCodes := []string{ - "admins", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "admins": resources_core.FormatString(plan.Admins), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sSthutrvalClusterUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sSthutrvalClusterUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sSthutrvalClusterUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state K8sSthutrvalClusterUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.K8sSthutrvalClusterID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "admins": resources_core.FormatString(plan.Admins), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *K8sSthutrvalClusterUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sSthutrvalClusterUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.K8sSthutrvalClusterID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "admins": resources_core.FormatString(state.Admins), - } - identityCodes := []string{ - "admins", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "admins": resources_core.FormatString(state.Admins), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *K8sSthutrvalClusterUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/19_vc_org_resource.go b/generated/test/go/19_vc_org_resource.go deleted file mode 100644 index b9a8ecb..0000000 --- a/generated/test/go/19_vc_org_resource.go +++ /dev/null @@ -1,397 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_org -// Service ID: 19 - -var _ resource.Resource = &VcOrgResource{} -var _ resource.ResourceWithModifyPlan = &VcOrgResource{} -var _ resource.ResourceWithImportState = &VcOrgResource{} - -type VcOrgResource struct { - client *core.UniversalClient -} - -type VcOrgModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - OrganizationType types.String `tfsdk:"organization_type"` - ResourceRealm types.String `tfsdk:"resource_realm"` - VIPConfigure types.String `tfsdk:"v_i_p_configure"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcOrgResource() resource.Resource { - return &VcOrgResource{} -} - -func (r *VcOrgResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_org" -} - -func (r *VcOrgResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "organization_type": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("iaas"), MarkdownDescription: "Доступ к организации предоставляется только при выборе `iaas` Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Облако в котором будет развёрнут тенант Не изменяется после создания."}, - "v_i_p_configure": schema.StringAttribute{Required: true}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcOrgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcOrgModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.OrganizationType.IsNull() && !plan.OrganizationType.IsUnknown() && !state.OrganizationType.IsNull() && !state.OrganizationType.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.OrganizationType.ValueString(), state.OrganizationType.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить organization_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - if config.VIPConfigure.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "v_i_p_configure is required.") - return - } - if config.VIPConfigure.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 418: resources_core.FormatString(config.ResourceRealm), - 556: resources_core.FormatString(config.OrganizationType), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 19, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcOrgResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.VIPConfigure.IsNull() || data.VIPConfigure.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "v_i_p_configure is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 19, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 418: resources_core.FormatString(data.ResourceRealm), - 556: resources_core.FormatString(data.OrganizationType), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 19, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 19, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 19, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcOrgResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcOrgModel - var state VcOrgModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.VIPConfigure.IsNull() != state.VIPConfigure.IsNull() || plan.VIPConfigure.IsUnknown() != state.VIPConfigure.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VIPConfigure.IsNull() && !plan.VIPConfigure.IsUnknown() && !state.VIPConfigure.IsNull() && !state.VIPConfigure.IsUnknown() { - if !strings.EqualFold(plan.VIPConfigure.ValueString(), state.VIPConfigure.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 662: resources_core.FormatString(plan.VIPConfigure), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 19, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "organizationType", Field: "OrganizationType", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "vIPConfigure", Field: "VIPConfigure", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcOrgModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcOrgResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcOrgResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/19_vc_org_user_resource.go b/generated/test/go/19_vc_org_user_resource.go deleted file mode 100644 index 2c8a9a0..0000000 --- a/generated/test/go/19_vc_org_user_resource.go +++ /dev/null @@ -1,347 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_org -// Subresource: user - -var _ resource.Resource = &VcOrgUserResource{} - -// VcOrgUserResource manages a subresource via operations. -type VcOrgUserResource struct { - client *core.UniversalClient -} - -type VcOrgUserModel struct { - ID types.String `tfsdk:"id"` - VcOrgID types.String `tfsdk:"vc_org_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Admins types.String `tfsdk:"admins"` -} - -func NewVcOrgUserResource() resource.Resource { - return &VcOrgUserResource{} -} - -func (r *VcOrgUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_org_user" -} - -func (r *VcOrgUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "vc_org_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "admins": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcOrgUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcOrgUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcOrgID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "admins": resources_core.FormatString(plan.Admins), - } - identityCodes := []string{ - "admins", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "admins": resources_core.FormatString(plan.Admins), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcOrgUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcOrgUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcOrgUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state VcOrgUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.VcOrgID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "admins": resources_core.FormatString(plan.Admins), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcOrgUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcOrgUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.VcOrgID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "admins": resources_core.FormatString(state.Admins), - } - identityCodes := []string{ - "admins", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "admins": resources_core.FormatString(state.Admins), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *VcOrgUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/1_dummy_resource.go b/generated/test/go/1_dummy_resource.go deleted file mode 100644 index 0abbb07..0000000 --- a/generated/test/go/1_dummy_resource.go +++ /dev/null @@ -1,576 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: dummy -// Service ID: 1 - -var _ resource.Resource = &DummyResource{} -var _ resource.ResourceWithModifyPlan = &DummyResource{} -var _ resource.ResourceWithImportState = &DummyResource{} - -type DummyResource struct { - client *core.UniversalClient -} - -type DummyModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - // --- Redeploy support (ARCHITECTURE.md) --- - // git_revision: при изменении вызывает redeploy вместо modify. - // Опциональное поле — если не задано, modify работает как обычно. - GitRevision types.String `tfsdk:"git_revision"` - Arr types.String `tfsdk:"arr"` - ArrayMapFixedExample types.String `tfsdk:"array_map_fixed_example"` - Bodymessage types.String `tfsdk:"bodymessage"` - DurationMs types.Int64 `tfsdk:"duration_ms"` - FailAtStart types.Bool `tfsdk:"fail_at_start"` - FailInProgress types.Bool `tfsdk:"fail_in_progress"` - JsonExample types.String `tfsdk:"json_example"` - MapExample types.String `tfsdk:"map_example"` - MapFixed types.String `tfsdk:"map_fixed"` - NestedRefExample types.String `tfsdk:"nested_ref_example"` - ResourceRealm types.String `tfsdk:"resource_realm"` - WhereFail types.Int64 `tfsdk:"where_fail"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewDummyResource() resource.Resource { - return &DummyResource{} -} - -func (r *DummyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_dummy" -} - -func (r *DummyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "arr": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "array_map_fixed_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Array of map-fixed Не изменяется после создания."}, - "bodymessage": schema.StringAttribute{Optional: true, MarkdownDescription: "Дата, уходящая в Vault"}, - "duration_ms": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0), MarkdownDescription: "перед завершением подождать (sleep) столько миллисекунд"}, - "fail_at_start": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "если true, завершить джоб, ничего не записывая в cmdb"}, - "fail_in_progress": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb"}, - "json_example": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "Для тестирования интерфейса", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "map_example": schema.StringAttribute{Optional: true}, - "map_fixed": schema.StringAttribute{Optional: true, MarkdownDescription: "Новый тип поля Не изменяется после создания."}, - "nested_ref_example": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "where_fail": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write"}, - // --- Redeploy support (ARCHITECTURE.md) --- - // При изменении git_revision вызывается redeploy вместо modify. - // Если не задано — modify работает без изменений. - "git_revision": schema.StringAttribute{Optional: true, MarkdownDescription: "Git revision (commit hash/tag). Changing this triggers redeploy instead of modify."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *DummyResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *DummyModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Arr.IsNull() && !plan.Arr.IsUnknown() && !state.Arr.IsNull() && !state.Arr.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Arr.ValueString(), state.Arr.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить arr", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ArrayMapFixedExample.IsNull() && !plan.ArrayMapFixedExample.IsUnknown() && !state.ArrayMapFixedExample.IsNull() && !state.ArrayMapFixedExample.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ArrayMapFixedExample.ValueString(), state.ArrayMapFixedExample.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить array_map_fixed_example", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.MapFixed.IsNull() && !plan.MapFixed.IsUnknown() && !state.MapFixed.IsNull() && !state.MapFixed.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.MapFixed.ValueString(), state.MapFixed.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить map_fixed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NestedRefExample.IsNull() && !plan.NestedRefExample.IsUnknown() && !state.NestedRefExample.IsNull() && !state.NestedRefExample.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.NestedRefExample.ValueString(), state.NestedRefExample.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить nested_ref_example", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Arr.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "arr is required.") - return - } - if config.Arr.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 198: resources_core.FormatInt64(config.DurationMs), - 199: resources_core.FormatBool(config.FailAtStart), - 200: resources_core.FormatBool(config.FailInProgress), - 201: resources_core.FormatInt64(config.WhereFail), - 242: resources_core.FormatString(config.ResourceRealm), - 286: resources_core.FormatString(config.Bodymessage), - 321: resources_core.FormatString(config.MapExample), - 322: resources_core.FormatString(config.JsonExample), - 396: resources_core.FormatString(config.NestedRefExample), - 647: resources_core.FormatString(config.MapFixed), - 654: resources_core.FormatString(config.ArrayMapFixedExample), - 863: resources_core.FormatString(config.Arr), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 1, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *DummyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Arr.IsNull() || data.Arr.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "arr is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 1, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 198: resources_core.FormatInt64(data.DurationMs), - 199: resources_core.FormatBool(data.FailAtStart), - 200: resources_core.FormatBool(data.FailInProgress), - 201: resources_core.FormatInt64(data.WhereFail), - 242: resources_core.FormatString(data.ResourceRealm), - 286: resources_core.FormatString(data.Bodymessage), - 321: resources_core.FormatString(data.MapExample), - 322: resources_core.FormatString(data.JsonExample), - 396: resources_core.FormatString(data.NestedRefExample), - 647: resources_core.FormatString(data.MapFixed), - 654: resources_core.FormatString(data.ArrayMapFixedExample), - 863: resources_core.FormatString(data.Arr), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 1, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 1, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arr", Field: "Arr", Type: "string"}, - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 1, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arr", Field: "Arr", Type: "string"}, - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *DummyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan DummyModel - var state DummyModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.DurationMs.IsNull() != state.DurationMs.IsNull() || plan.DurationMs.IsUnknown() != state.DurationMs.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.DurationMs.IsNull() && !plan.DurationMs.IsUnknown() && !state.DurationMs.IsNull() && !state.DurationMs.IsUnknown() { - if plan.DurationMs.ValueInt64() != state.DurationMs.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.FailAtStart.IsNull() != state.FailAtStart.IsNull() || plan.FailAtStart.IsUnknown() != state.FailAtStart.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.FailAtStart.IsNull() && !plan.FailAtStart.IsUnknown() && !state.FailAtStart.IsNull() && !state.FailAtStart.IsUnknown() { - if plan.FailAtStart.ValueBool() != state.FailAtStart.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.FailInProgress.IsNull() != state.FailInProgress.IsNull() || plan.FailInProgress.IsUnknown() != state.FailInProgress.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.FailInProgress.IsNull() && !plan.FailInProgress.IsUnknown() && !state.FailInProgress.IsNull() && !state.FailInProgress.IsUnknown() { - if plan.FailInProgress.ValueBool() != state.FailInProgress.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.WhereFail.IsNull() != state.WhereFail.IsNull() || plan.WhereFail.IsUnknown() != state.WhereFail.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.WhereFail.IsNull() && !plan.WhereFail.IsUnknown() && !state.WhereFail.IsNull() && !state.WhereFail.IsUnknown() { - if plan.WhereFail.ValueInt64() != state.WhereFail.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.Bodymessage.IsNull() != state.Bodymessage.IsNull() || plan.Bodymessage.IsUnknown() != state.Bodymessage.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.Bodymessage.IsNull() && !plan.Bodymessage.IsUnknown() && !state.Bodymessage.IsNull() && !state.Bodymessage.IsUnknown() { - if !strings.EqualFold(plan.Bodymessage.ValueString(), state.Bodymessage.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MapExample.IsNull() != state.MapExample.IsNull() || plan.MapExample.IsUnknown() != state.MapExample.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MapExample.IsNull() && !plan.MapExample.IsUnknown() && !state.MapExample.IsNull() && !state.MapExample.IsUnknown() { - if !strings.EqualFold(plan.MapExample.ValueString(), state.MapExample.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonExample.IsNull() != state.JsonExample.IsNull() || plan.JsonExample.IsUnknown() != state.JsonExample.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonExample.IsNull() && !plan.JsonExample.IsUnknown() && !state.JsonExample.IsNull() && !state.JsonExample.IsUnknown() { - if !strings.EqualFold(plan.JsonExample.ValueString(), state.JsonExample.ValueString()) { - hasServiceParamChanges = true - } - } - } - // --- Redeploy support (ARCHITECTURE.md) --- - // Проверяем изменился ли git_revision. - // Если да — вызываем redeploy вместо modify. - // git_revision = "" (не задано) → обычный modify. - redeployRequested := false - if !plan.GitRevision.IsNull() && !plan.GitRevision.IsUnknown() { - if state.GitRevision.IsNull() || state.GitRevision.IsUnknown() || plan.GitRevision.ValueString() != state.GitRevision.ValueString() { - redeployRequested = true - } - } - - if !hasServiceParamChanges && !redeployRequested { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - // --- Redeploy support (ARCHITECTURE.md) --- - if redeployRequested { - // Вызываем redeploy — пустой params (операция не требует CFS-параметров) - if err := r.client.RunRedeployOperation(ctx, instanceID.ValueString(), operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } else { - params := map[int]string{ - 287: resources_core.FormatInt64(plan.DurationMs), - 288: resources_core.FormatBool(plan.FailAtStart), - 289: resources_core.FormatBool(plan.FailInProgress), - 290: resources_core.FormatInt64(plan.WhereFail), - 291: resources_core.FormatString(plan.Bodymessage), - 373: resources_core.FormatString(plan.MapExample), - 374: resources_core.FormatString(plan.JsonExample), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 1, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "arr", Field: "Arr", Type: "string"}, - {Code: "arrayMapFixedExample", Field: "ArrayMapFixedExample", Type: "string"}, - {Code: "bodymessage", Field: "Bodymessage", Type: "string"}, - {Code: "durationMs", Field: "DurationMs", Type: "int64"}, - {Code: "failAtStart", Field: "FailAtStart", Type: "bool"}, - {Code: "failInProgress", Field: "FailInProgress", Type: "bool"}, - {Code: "jsonExample", Field: "JsonExample", Type: "string"}, - {Code: "mapExample", Field: "MapExample", Type: "string"}, - {Code: "mapFixed", Field: "MapFixed", Type: "string"}, - {Code: "nestedRefExample", Field: "NestedRefExample", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "whereFail", Field: "WhereFail", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *DummyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state DummyModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *DummyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *DummyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/20_vc_org_saas_resource.go b/generated/test/go/20_vc_org_saas_resource.go deleted file mode 100644 index 6116681..0000000 --- a/generated/test/go/20_vc_org_saas_resource.go +++ /dev/null @@ -1,353 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_org_saas -// Service ID: 20 - -var _ resource.Resource = &VcOrgSaasResource{} -var _ resource.ResourceWithModifyPlan = &VcOrgSaasResource{} -var _ resource.ResourceWithImportState = &VcOrgSaasResource{} - -type VcOrgSaasResource struct { - client *core.UniversalClient -} - -type VcOrgSaasModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcOrgSaasResource() resource.Resource { - return &VcOrgSaasResource{} -} - -func (r *VcOrgSaasResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_org_saas" -} - -func (r *VcOrgSaasResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcOrgSaasResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcOrgSaasModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcOrgSaasModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcOrgSaasModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 185: resources_core.FormatString(config.ResourceRealm), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 20, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcOrgSaasResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcOrgSaasModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 20, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 185: resources_core.FormatString(data.ResourceRealm), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 20, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 20, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgSaasResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcOrgSaasModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 20, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcOrgSaasResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcOrgSaasModel - var state VcOrgSaasModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 20, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcOrgSaasResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcOrgSaasModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcOrgSaasResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcOrgSaasResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/21_vc_vdc_resource.go b/generated/test/go/21_vc_vdc_resource.go deleted file mode 100644 index 0cc7279..0000000 --- a/generated/test/go/21_vc_vdc_resource.go +++ /dev/null @@ -1,568 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc -// Service ID: 21 - -var _ resource.Resource = &VcVdcResource{} -var _ resource.ResourceWithModifyPlan = &VcVdcResource{} -var _ resource.ResourceWithImportState = &VcVdcResource{} - -type VcVdcResource struct { - client *core.UniversalClient -} - -type VcVdcModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - CpuAllocated types.Int64 `tfsdk:"cpu_allocated"` - CpuGuaranteed types.Int64 `tfsdk:"cpu_guaranteed"` - MemAllocated types.Int64 `tfsdk:"mem_allocated"` - NetworkProvider types.String `tfsdk:"network_provider"` - OrganizationUid types.String `tfsdk:"organization_uid"` - ProviderVdc types.String `tfsdk:"provider_vdc"` - StorageConfig types.String `tfsdk:"storage_config"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVdcResource() resource.Resource { - return &VcVdcResource{} -} - -func (r *VcVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc" -} - -func (r *VcVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "cpu_allocated": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(80), MarkdownDescription: "шт"}, - "cpu_guaranteed": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(20), MarkdownDescription: "% резервирования Не изменяется после создания."}, - "mem_allocated": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "gb"}, - "network_provider": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "organization_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` Не изменяется после создания."}, - "provider_vdc": schema.StringAttribute{Required: true, MarkdownDescription: "Приписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
Не изменяется после создания."}, - "storage_config": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Первая политика в списке указывается как "По умолчанию""}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVdcModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.CpuGuaranteed.IsNull() && !plan.CpuGuaranteed.IsUnknown() && !state.CpuGuaranteed.IsNull() && !state.CpuGuaranteed.IsUnknown() { - if plan.CpuGuaranteed.ValueInt64() != state.CpuGuaranteed.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить cpu_guaranteed", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.NetworkProvider.IsNull() && !plan.NetworkProvider.IsUnknown() && !state.NetworkProvider.IsNull() && !state.NetworkProvider.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.NetworkProvider.ValueString(), state.NetworkProvider.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить network_provider", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.OrganizationUid.IsNull() && !plan.OrganizationUid.IsUnknown() && !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.OrganizationUid.ValueString(), state.OrganizationUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить organization_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ProviderVdc.IsNull() && !plan.ProviderVdc.IsUnknown() && !state.ProviderVdc.IsNull() && !state.ProviderVdc.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ProviderVdc.ValueString(), state.ProviderVdc.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить provider_vdc", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.NetworkProvider.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "network_provider is required.") - return - } - if config.NetworkProvider.IsUnknown() { - return - } - if config.OrganizationUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "organization_uid is required.") - return - } - if config.OrganizationUid.IsUnknown() { - return - } - if config.ProviderVdc.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "provider_vdc is required.") - return - } - if config.ProviderVdc.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.OrganizationUid.IsNull() && !config.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, config.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != config.OrganizationUid.ValueString() { - config.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - params := map[int]string{ - 30: resources_core.FormatString(config.OrganizationUid), - 335: resources_core.FormatString(config.ProviderVdc), - 361: resources_core.FormatString(config.StorageConfig), - 397: resources_core.FormatInt64(config.CpuGuaranteed), - 557: resources_core.FormatInt64(config.CpuAllocated), - 558: resources_core.FormatInt64(config.MemAllocated), - 746: resources_core.FormatString(config.NetworkProvider), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 21, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.NetworkProvider.IsNull() || data.NetworkProvider.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "network_provider is required.") - return - } - if data.OrganizationUid.IsNull() || data.OrganizationUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "organization_uid is required.") - return - } - if data.ProviderVdc.IsNull() || data.ProviderVdc.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "provider_vdc is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalOrganizationUid := data.OrganizationUid - if !data.OrganizationUid.IsNull() && !data.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, data.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedOrganizationUid != "" && resolvedOrganizationUid != data.OrganizationUid.ValueString() { - data.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 21, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 30: resources_core.FormatString(data.OrganizationUid), - 335: resources_core.FormatString(data.ProviderVdc), - 361: resources_core.FormatString(data.StorageConfig), - 397: resources_core.FormatInt64(data.CpuGuaranteed), - 557: resources_core.FormatInt64(data.CpuAllocated), - 558: resources_core.FormatInt64(data.MemAllocated), - 746: resources_core.FormatString(data.NetworkProvider), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 21, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 21, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, state.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != state.OrganizationUid.ValueString() { - state.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalOrganizationUid.IsNull() && !originalOrganizationUid.IsUnknown() && !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - if strings.EqualFold(state.OrganizationUid.ValueString(), originalOrganizationUid.ValueString()) { - state.OrganizationUid = originalOrganizationUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 21, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.OrganizationUid.IsNull() && !newState.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, newState.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != newState.OrganizationUid.ValueString() { - newState.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() && !newState.OrganizationUid.IsNull() && !newState.OrganizationUid.IsUnknown() { - if strings.EqualFold(newState.OrganizationUid.ValueString(), state.OrganizationUid.ValueString()) { - newState.OrganizationUid = state.OrganizationUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcModel - var state VcVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.CpuAllocated.IsNull() != state.CpuAllocated.IsNull() || plan.CpuAllocated.IsUnknown() != state.CpuAllocated.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.CpuAllocated.IsNull() && !plan.CpuAllocated.IsUnknown() && !state.CpuAllocated.IsNull() && !state.CpuAllocated.IsUnknown() { - if plan.CpuAllocated.ValueInt64() != state.CpuAllocated.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MemAllocated.IsNull() != state.MemAllocated.IsNull() || plan.MemAllocated.IsUnknown() != state.MemAllocated.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MemAllocated.IsNull() && !plan.MemAllocated.IsUnknown() && !state.MemAllocated.IsNull() && !state.MemAllocated.IsUnknown() { - if plan.MemAllocated.ValueInt64() != state.MemAllocated.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.StorageConfig.IsNull() != state.StorageConfig.IsNull() || plan.StorageConfig.IsUnknown() != state.StorageConfig.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.StorageConfig.IsNull() && !plan.StorageConfig.IsUnknown() && !state.StorageConfig.IsNull() && !state.StorageConfig.IsUnknown() { - if !strings.EqualFold(plan.StorageConfig.ValueString(), state.StorageConfig.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 560: resources_core.FormatInt64(plan.CpuAllocated), - 561: resources_core.FormatInt64(plan.MemAllocated), - 562: resources_core.FormatString(plan.StorageConfig), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 21, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "cpuAllocated", Field: "CpuAllocated", Type: "int64"}, - {Code: "cpuGuaranteed", Field: "CpuGuaranteed", Type: "int64"}, - {Code: "memAllocated", Field: "MemAllocated", Type: "int64"}, - {Code: "networkProvider", Field: "NetworkProvider", Type: "string"}, - {Code: "organizationUid", Field: "OrganizationUid", Type: "string"}, - {Code: "providerVdc", Field: "ProviderVdc", Type: "string"}, - {Code: "storageConfig", Field: "StorageConfig", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - resolvedOrganizationUid, err := r.client.ResolveRefSvcParamValue(ctx, 19, state.OrganizationUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve organization_uid", err.Error()) - } else if resolvedOrganizationUid != "" && resolvedOrganizationUid != state.OrganizationUid.ValueString() { - state.OrganizationUid = types.StringValue(resolvedOrganizationUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.OrganizationUid.IsNull() && !plan.OrganizationUid.IsUnknown() && !state.OrganizationUid.IsNull() && !state.OrganizationUid.IsUnknown() { - if strings.EqualFold(state.OrganizationUid.ValueString(), plan.OrganizationUid.ValueString()) { - state.OrganizationUid = plan.OrganizationUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVdcResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVdcResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/22_vc_nsxt_resource.go b/generated/test/go/22_vc_nsxt_resource.go deleted file mode 100644 index 7184b1a..0000000 --- a/generated/test/go/22_vc_nsxt_resource.go +++ /dev/null @@ -1,609 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_nsxt -// Service ID: 22 - -var _ resource.Resource = &VcNsxtResource{} -var _ resource.ResourceWithModifyPlan = &VcNsxtResource{} -var _ resource.ResourceWithImportState = &VcNsxtResource{} - -type VcNsxtResource struct { - client *core.UniversalClient -} - -type VcNsxtModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - NeedEnableAVI types.Bool `tfsdk:"need_enable_a_v_i"` - QosProfile types.String `tfsdk:"qos_profile"` - VdcGroupUid types.String `tfsdk:"vdc_group_uid"` - VdcType types.String `tfsdk:"vdc_type"` - VdcUid types.String `tfsdk:"vdc_uid"` - VirtualServicesCount types.Int64 `tfsdk:"virtual_services_count"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcNsxtResource() resource.Resource { - return &VcNsxtResource{} -} - -func (r *VcNsxtResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_nsxt" -} - -func (r *VcNsxtResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Имя ip Space для внешнего IP"}, - "need_enable_a_v_i": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Включение Load Balancer"}, - "qos_profile": schema.StringAttribute{Optional: true, MarkdownDescription: "Параметр пока не работает
Должен возвращать поле из ресурсной платформы типа vc из .vcd.hardware.gatewayQoSProfiles

Как по идее должен работать.
Нужно заполнить или CFS vdcUid, или vdcGroupUid
Идеально конечно проверять `if (params.vdcType == "vdc" && params.vdcUid != "")` или `if (params.vdcType == "vdcGroup" && params.vdcGroupUid != "")`

Далее надо пойти по стейту vdc -> org -> resPlatform, взять gatewayQoSProfiles
Или пойти по стейту vdcgroup -> vdc -> org -> resPlatform, взять gatewayQoSProfiles

Регулярку могу написать (Виталя)"}, - "vdc_group_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UUID Услуги `Группа виртуальных датацентров (groupvDC)` Не изменяется после создания."}, - "vdc_type": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("vdc"), MarkdownDescription: "Тип родительской услуги Не изменяется после создания."}, - "vdc_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UUID Услуги `Виртуальный датацентр (vDC)` Не изменяется после создания."}, - "virtual_services_count": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Кол-во виртуальных сервисов, которые **резервируются** на AVI"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcNsxtResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcNsxtModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.VdcGroupUid.IsNull() && !plan.VdcGroupUid.IsUnknown() && !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VdcGroupUid.ValueString(), state.VdcGroupUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vdc_group_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcType.IsNull() && !plan.VdcType.IsUnknown() && !state.VdcType.IsNull() && !state.VdcType.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VdcType.ValueString(), state.VdcType.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vdc_type", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VdcUid.ValueString(), state.VdcUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VdcGroupUid.IsNull() && !config.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, config.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != config.VdcGroupUid.ValueString() { - config.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 8: resources_core.FormatString(config.VdcUid), - 340: resources_core.FormatBool(config.NeedEnableAVI), - 341: resources_core.FormatInt64(config.VirtualServicesCount), - 621: resources_core.FormatString(config.VdcType), - 622: resources_core.FormatString(config.VdcGroupUid), - 825: resources_core.FormatString(config.QosProfile), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 22, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcNsxtResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalVdcGroupUid := data.VdcGroupUid - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalVdcUid := data.VdcUid - if !data.VdcGroupUid.IsNull() && !data.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, data.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != data.VdcGroupUid.ValueString() { - data.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 22, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 8: resources_core.FormatString(data.VdcUid), - 340: resources_core.FormatBool(data.NeedEnableAVI), - 341: resources_core.FormatInt64(data.VirtualServicesCount), - 621: resources_core.FormatString(data.VdcType), - 622: resources_core.FormatString(data.VdcGroupUid), - 825: resources_core.FormatString(data.QosProfile), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 22, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 22, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "qosProfile", Field: "QosProfile", Type: "string"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, state.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != state.VdcGroupUid.ValueString() { - state.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalVdcGroupUid.IsNull() && !originalVdcGroupUid.IsUnknown() && !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - if strings.EqualFold(state.VdcGroupUid.ValueString(), originalVdcGroupUid.ValueString()) { - state.VdcGroupUid = originalVdcGroupUid - } - } - if !originalVdcUid.IsNull() && !originalVdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if strings.EqualFold(state.VdcUid.ValueString(), originalVdcUid.ValueString()) { - state.VdcUid = originalVdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcNsxtResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 22, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "qosProfile", Field: "QosProfile", Type: "string"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VdcGroupUid.IsNull() && !newState.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, newState.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != newState.VdcGroupUid.ValueString() { - newState.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() && !newState.VdcGroupUid.IsNull() && !newState.VdcGroupUid.IsUnknown() { - if strings.EqualFold(newState.VdcGroupUid.ValueString(), state.VdcGroupUid.ValueString()) { - newState.VdcGroupUid = state.VdcGroupUid - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() && !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - if strings.EqualFold(newState.VdcUid.ValueString(), state.VdcUid.ValueString()) { - newState.VdcUid = state.VdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcNsxtResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcNsxtModel - var state VcNsxtModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.NeedEnableAVI.IsNull() != state.NeedEnableAVI.IsNull() || plan.NeedEnableAVI.IsUnknown() != state.NeedEnableAVI.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedEnableAVI.IsNull() && !plan.NeedEnableAVI.IsUnknown() && !state.NeedEnableAVI.IsNull() && !state.NeedEnableAVI.IsUnknown() { - if plan.NeedEnableAVI.ValueBool() != state.NeedEnableAVI.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VirtualServicesCount.IsNull() != state.VirtualServicesCount.IsNull() || plan.VirtualServicesCount.IsUnknown() != state.VirtualServicesCount.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VirtualServicesCount.IsNull() && !plan.VirtualServicesCount.IsUnknown() && !state.VirtualServicesCount.IsNull() && !state.VirtualServicesCount.IsUnknown() { - if plan.VirtualServicesCount.ValueInt64() != state.VirtualServicesCount.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if !strings.EqualFold(plan.IpSpaceName.ValueString(), state.IpSpaceName.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.QosProfile.IsNull() != state.QosProfile.IsNull() || plan.QosProfile.IsUnknown() != state.QosProfile.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.QosProfile.IsNull() && !plan.QosProfile.IsUnknown() && !state.QosProfile.IsNull() && !state.QosProfile.IsUnknown() { - if !strings.EqualFold(plan.QosProfile.ValueString(), state.QosProfile.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 368: resources_core.FormatBool(plan.NeedEnableAVI), - 369: resources_core.FormatInt64(plan.VirtualServicesCount), - 372: resources_core.FormatString(plan.IpSpaceName), - 856: resources_core.FormatString(plan.QosProfile), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 22, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "needEnableAVI", Field: "NeedEnableAVI", Type: "bool"}, - {Code: "qosProfile", Field: "QosProfile", Type: "string"}, - {Code: "vdcGroupUid", Field: "VdcGroupUid", Type: "string"}, - {Code: "vdcType", Field: "VdcType", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - {Code: "virtualServicesCount", Field: "VirtualServicesCount", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - resolvedVdcGroupUid, err := r.client.ResolveRefSvcParamValue(ctx, 29, state.VdcGroupUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_group_uid", err.Error()) - } else if resolvedVdcGroupUid != "" && resolvedVdcGroupUid != state.VdcGroupUid.ValueString() { - state.VdcGroupUid = types.StringValue(resolvedVdcGroupUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.VdcGroupUid.IsNull() && !plan.VdcGroupUid.IsUnknown() && !state.VdcGroupUid.IsNull() && !state.VdcGroupUid.IsUnknown() { - if strings.EqualFold(state.VdcGroupUid.ValueString(), plan.VdcGroupUid.ValueString()) { - state.VdcGroupUid = plan.VdcGroupUid - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if strings.EqualFold(state.VdcUid.ValueString(), plan.VdcUid.ValueString()) { - state.VdcUid = plan.VdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcNsxtResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcNsxtModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcNsxtResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcNsxtResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/23_vc_vm_resource.go b/generated/test/go/23_vc_vm_resource.go deleted file mode 100644 index d5275df..0000000 --- a/generated/test/go/23_vc_vm_resource.go +++ /dev/null @@ -1,576 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm -// Service ID: 23 - -var _ resource.Resource = &VcVmResource{} -var _ resource.ResourceWithModifyPlan = &VcVmResource{} -var _ resource.ResourceWithImportState = &VcVmResource{} - -type VcVmResource struct { - client *core.UniversalClient -} - -type VcVmModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessIpList types.String `tfsdk:"access_ip_list"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - TemplateName types.String `tfsdk:"template_name"` - VappUid types.String `tfsdk:"vapp_uid"` - VmCpu types.String `tfsdk:"vm_cpu"` - VmDisksize types.String `tfsdk:"vm_disksize"` - VmName types.String `tfsdk:"vm_name"` - VmRam types.String `tfsdk:"vm_ram"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVmResource() resource.Resource { - return &VcVmResource{} -} - -func (r *VcVmResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm" -} - -func (r *VcVmResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_ip_list": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("79.111.119.78/32 185.247.187.1/32"), MarkdownDescription: "Вставить содержимое из 'curl ifconfig.io'
IP адреса в CIDR формате через пробел для настройки аксес листов"}, - "ip_space_name": schema.StringAttribute{Required: true, MarkdownDescription: "Брать из свойств ресурсной платформы
.vcd.ipSpace

Имя IP-space для выделения внешнего IP (IP выделяется обязательно) Не изменяется после создания."}, - "template_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("RockyLinux_9-16G"), MarkdownDescription: "ОС Не изменяется после создания."}, - "vapp_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "InstanceUid vApp. vApp должен быть создан Не изменяется после создания."}, - "vm_cpu": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("2"), MarkdownDescription: "CPU"}, - "vm_disksize": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("10"), MarkdownDescription: "Размер диска под сервис (GB)"}, - "vm_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("vm0001"), MarkdownDescription: "Имя ВМ. Не поддерживает спец-символы Не изменяется после создания."}, - "vm_ram": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("2"), MarkdownDescription: "RAM (GB)"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVmModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVmModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVmModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.IpSpaceName.ValueString(), state.IpSpaceName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить ip_space_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.TemplateName.IsNull() && !plan.TemplateName.IsUnknown() && !state.TemplateName.IsNull() && !state.TemplateName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.TemplateName.ValueString(), state.TemplateName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить template_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VappUid.ValueString(), state.VappUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vapp_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VmName.IsNull() && !plan.VmName.IsUnknown() && !state.VmName.IsNull() && !state.VmName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VmName.ValueString(), state.VmName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vm_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.IpSpaceName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if config.IpSpaceName.IsUnknown() { - return - } - if config.VappUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - if config.VappUid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VappUid.IsNull() && !config.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, config.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != config.VappUid.ValueString() { - config.VappUid = types.StringValue(resolvedVappUid) - } - } - params := map[int]string{ - 33: resources_core.FormatString(config.VappUid), - 35: resources_core.FormatString(config.VmName), - 36: resources_core.FormatString(config.VmCpu), - 37: resources_core.FormatString(config.VmRam), - 38: resources_core.FormatString(config.VmDisksize), - 176: resources_core.FormatString(config.TemplateName), - 177: resources_core.FormatString(config.AccessIpList), - 406: resources_core.FormatString(config.IpSpaceName), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 23, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVmResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVmModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if data.VappUid.IsNull() || data.VappUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalVappUid := data.VappUid - if !data.VappUid.IsNull() && !data.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, data.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVappUid != "" && resolvedVappUid != data.VappUid.ValueString() { - data.VappUid = types.StringValue(resolvedVappUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 23, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 33: resources_core.FormatString(data.VappUid), - 35: resources_core.FormatString(data.VmName), - 36: resources_core.FormatString(data.VmCpu), - 37: resources_core.FormatString(data.VmRam), - 38: resources_core.FormatString(data.VmDisksize), - 176: resources_core.FormatString(data.TemplateName), - 177: resources_core.FormatString(data.AccessIpList), - 406: resources_core.FormatString(data.IpSpaceName), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 23, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 23, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "templateName", Field: "TemplateName", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "string"}, - {Code: "vmDisksize", Field: "VmDisksize", Type: "string"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalVappUid.IsNull() && !originalVappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - if strings.EqualFold(state.VappUid.ValueString(), originalVappUid.ValueString()) { - state.VappUid = originalVappUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 23, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "templateName", Field: "TemplateName", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "string"}, - {Code: "vmDisksize", Field: "VmDisksize", Type: "string"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VappUid.IsNull() && !newState.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, newState.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != newState.VappUid.ValueString() { - newState.VappUid = types.StringValue(resolvedVappUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() && !newState.VappUid.IsNull() && !newState.VappUid.IsUnknown() { - if strings.EqualFold(newState.VappUid.ValueString(), state.VappUid.ValueString()) { - newState.VappUid = state.VappUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVmResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmModel - var state VcVmModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.VmCpu.IsNull() != state.VmCpu.IsNull() || plan.VmCpu.IsUnknown() != state.VmCpu.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmCpu.IsNull() && !plan.VmCpu.IsUnknown() && !state.VmCpu.IsNull() && !state.VmCpu.IsUnknown() { - if !strings.EqualFold(plan.VmCpu.ValueString(), state.VmCpu.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmRam.IsNull() != state.VmRam.IsNull() || plan.VmRam.IsUnknown() != state.VmRam.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmRam.IsNull() && !plan.VmRam.IsUnknown() && !state.VmRam.IsNull() && !state.VmRam.IsUnknown() { - if !strings.EqualFold(plan.VmRam.ValueString(), state.VmRam.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmDisksize.IsNull() != state.VmDisksize.IsNull() || plan.VmDisksize.IsUnknown() != state.VmDisksize.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmDisksize.IsNull() && !plan.VmDisksize.IsUnknown() && !state.VmDisksize.IsNull() && !state.VmDisksize.IsUnknown() { - if !strings.EqualFold(plan.VmDisksize.ValueString(), state.VmDisksize.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessIpList.IsNull() != state.AccessIpList.IsNull() || plan.AccessIpList.IsUnknown() != state.AccessIpList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessIpList.IsNull() && !plan.AccessIpList.IsUnknown() && !state.AccessIpList.IsNull() && !state.AccessIpList.IsUnknown() { - if !strings.EqualFold(plan.AccessIpList.ValueString(), state.AccessIpList.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 186: resources_core.FormatString(plan.VmCpu), - 187: resources_core.FormatString(plan.VmRam), - 188: resources_core.FormatString(plan.VmDisksize), - 189: resources_core.FormatString(plan.AccessIpList), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 23, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "templateName", Field: "TemplateName", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "string"}, - {Code: "vmDisksize", Field: "VmDisksize", Type: "string"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - if strings.EqualFold(state.VappUid.ValueString(), plan.VappUid.ValueString()) { - state.VappUid = plan.VappUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVmModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVmResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVmResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/25_vcexternalip_resource.go b/generated/test/go/25_vcexternalip_resource.go deleted file mode 100644 index fc31693..0000000 --- a/generated/test/go/25_vcexternalip_resource.go +++ /dev/null @@ -1,610 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vcexternalip -// Service ID: 25 - -var _ resource.Resource = &VcexternalipResource{} -var _ resource.ResourceWithModifyPlan = &VcexternalipResource{} -var _ resource.ResourceWithImportState = &VcexternalipResource{} - -type VcexternalipResource struct { - client *core.UniversalClient -} - -type VcexternalipModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DnatCreate types.Bool `tfsdk:"dnat_create"` - FromServiceCloudEdgeName types.String `tfsdk:"from_service_cloud_edge_name"` - FromServiceCloudEdgeScope types.String `tfsdk:"from_service_cloud_edge_scope"` - FromServiceCloudOrgName types.String `tfsdk:"from_service_cloud_org_name"` - FromServiceCloudVdcName types.String `tfsdk:"from_service_cloud_vdc_name"` - FromServiceCloudVmwareUrl types.String `tfsdk:"from_service_cloud_vmware_url"` - FromServiceNamespace types.String `tfsdk:"from_service_namespace"` - FromServiceVdcGroupName types.String `tfsdk:"from_service_vdc_group_name"` - InternalAddrAccess types.String `tfsdk:"internal_addr_access"` - InternalPortAccess types.String `tfsdk:"internal_port_access"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - ResourceRealm types.String `tfsdk:"resource_realm"` - ServiceUid types.String `tfsdk:"service_uid"` - SnatCreate types.Bool `tfsdk:"snat_create"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcexternalipResource() resource.Resource { - return &VcexternalipResource{} -} - -func (r *VcexternalipResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vcexternalip" -} - -func (r *VcexternalipResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "dnat_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true), MarkdownDescription: "Необходимо создать DNAT-правило."}, - "from_service_cloud_edge_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Edge составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_edge_scope": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "from_service_cloud_org_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Org составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_vdc_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Vdc составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_cloud_vmware_url": schema.StringAttribute{Optional: true, MarkdownDescription: "Api-Url составной услуги (указывать, если resourceRealm связан с CloudDirector) Не изменяется после создания."}, - "from_service_namespace": schema.StringAttribute{Required: true, MarkdownDescription: "Namespace составной услуги (для отображения правил FW) Не изменяется после создания."}, - "from_service_vdc_group_name": schema.StringAttribute{Optional: true, MarkdownDescription: "Не изменяется после создания."}, - "internal_addr_access": schema.StringAttribute{Required: true, MarkdownDescription: "Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true"}, - "internal_port_access": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("5432"), MarkdownDescription: "Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
"}, - "ip_space_name": schema.StringAttribute{Required: true, MarkdownDescription: "Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "service_uid": schema.StringAttribute{Required: true}, - "snat_create": schema.BoolAttribute{Optional: true, MarkdownDescription: "Необходимо создать SNAT-правило.
"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcexternalipResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcexternalipModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.FromServiceCloudEdgeName.IsNull() && !plan.FromServiceCloudEdgeName.IsUnknown() && !state.FromServiceCloudEdgeName.IsNull() && !state.FromServiceCloudEdgeName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.FromServiceCloudEdgeName.ValueString(), state.FromServiceCloudEdgeName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_edge_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudEdgeScope.IsNull() && !plan.FromServiceCloudEdgeScope.IsUnknown() && !state.FromServiceCloudEdgeScope.IsNull() && !state.FromServiceCloudEdgeScope.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.FromServiceCloudEdgeScope.ValueString(), state.FromServiceCloudEdgeScope.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_edge_scope", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudOrgName.IsNull() && !plan.FromServiceCloudOrgName.IsUnknown() && !state.FromServiceCloudOrgName.IsNull() && !state.FromServiceCloudOrgName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.FromServiceCloudOrgName.ValueString(), state.FromServiceCloudOrgName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_org_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudVdcName.IsNull() && !plan.FromServiceCloudVdcName.IsUnknown() && !state.FromServiceCloudVdcName.IsNull() && !state.FromServiceCloudVdcName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.FromServiceCloudVdcName.ValueString(), state.FromServiceCloudVdcName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_vdc_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceCloudVmwareUrl.IsNull() && !plan.FromServiceCloudVmwareUrl.IsUnknown() && !state.FromServiceCloudVmwareUrl.IsNull() && !state.FromServiceCloudVmwareUrl.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.FromServiceCloudVmwareUrl.ValueString(), state.FromServiceCloudVmwareUrl.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить from_service_cloud_vmware_url", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceNamespace.IsNull() && !plan.FromServiceNamespace.IsUnknown() && !state.FromServiceNamespace.IsNull() && !state.FromServiceNamespace.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.FromServiceNamespace.ValueString(), state.FromServiceNamespace.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить from_service_namespace", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.FromServiceVdcGroupName.IsNull() && !plan.FromServiceVdcGroupName.IsUnknown() && !state.FromServiceVdcGroupName.IsNull() && !state.FromServiceVdcGroupName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.FromServiceVdcGroupName.ValueString(), state.FromServiceVdcGroupName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить from_service_vdc_group_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.FromServiceNamespace.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "from_service_namespace is required.") - return - } - if config.FromServiceNamespace.IsUnknown() { - return - } - if config.InternalAddrAccess.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "internal_addr_access is required.") - return - } - if config.InternalAddrAccess.IsUnknown() { - return - } - if config.IpSpaceName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if config.IpSpaceName.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - if config.ServiceUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "service_uid is required.") - return - } - if config.ServiceUid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 140: resources_core.FormatString(config.ServiceUid), - 141: resources_core.FormatBool(config.DnatCreate), - 142: resources_core.FormatString(config.InternalPortAccess), - 143: resources_core.FormatBool(config.SnatCreate), - 144: resources_core.FormatString(config.InternalAddrAccess), - 324: resources_core.FormatString(config.FromServiceNamespace), - 325: resources_core.FormatString(config.FromServiceCloudEdgeName), - 326: resources_core.FormatString(config.FromServiceCloudVdcName), - 327: resources_core.FormatString(config.FromServiceCloudOrgName), - 328: resources_core.FormatString(config.FromServiceCloudVmwareUrl), - 336: resources_core.FormatString(config.IpSpaceName), - 488: resources_core.FormatString(config.ResourceRealm), - 624: resources_core.FormatString(config.FromServiceCloudEdgeScope), - 626: resources_core.FormatString(config.FromServiceVdcGroupName), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 25, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcexternalipResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.FromServiceNamespace.IsNull() || data.FromServiceNamespace.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "from_service_namespace is required.") - return - } - if data.InternalAddrAccess.IsNull() || data.InternalAddrAccess.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "internal_addr_access is required.") - return - } - if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.ServiceUid.IsNull() || data.ServiceUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "service_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 25, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 140: resources_core.FormatString(data.ServiceUid), - 141: resources_core.FormatBool(data.DnatCreate), - 142: resources_core.FormatString(data.InternalPortAccess), - 143: resources_core.FormatBool(data.SnatCreate), - 144: resources_core.FormatString(data.InternalAddrAccess), - 324: resources_core.FormatString(data.FromServiceNamespace), - 325: resources_core.FormatString(data.FromServiceCloudEdgeName), - 326: resources_core.FormatString(data.FromServiceCloudVdcName), - 327: resources_core.FormatString(data.FromServiceCloudOrgName), - 328: resources_core.FormatString(data.FromServiceCloudVmwareUrl), - 336: resources_core.FormatString(data.IpSpaceName), - 488: resources_core.FormatString(data.ResourceRealm), - 624: resources_core.FormatString(data.FromServiceCloudEdgeScope), - 626: resources_core.FormatString(data.FromServiceVdcGroupName), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 25, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 25, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcexternalipResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 25, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcexternalipResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcexternalipModel - var state VcexternalipModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ServiceUid.IsNull() != state.ServiceUid.IsNull() || plan.ServiceUid.IsUnknown() != state.ServiceUid.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ServiceUid.IsNull() && !plan.ServiceUid.IsUnknown() && !state.ServiceUid.IsNull() && !state.ServiceUid.IsUnknown() { - if !strings.EqualFold(plan.ServiceUid.ValueString(), state.ServiceUid.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if !strings.EqualFold(plan.IpSpaceName.ValueString(), state.IpSpaceName.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.DnatCreate.IsNull() != state.DnatCreate.IsNull() || plan.DnatCreate.IsUnknown() != state.DnatCreate.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.DnatCreate.IsNull() && !plan.DnatCreate.IsUnknown() && !state.DnatCreate.IsNull() && !state.DnatCreate.IsUnknown() { - if plan.DnatCreate.ValueBool() != state.DnatCreate.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.SnatCreate.IsNull() != state.SnatCreate.IsNull() || plan.SnatCreate.IsUnknown() != state.SnatCreate.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.SnatCreate.IsNull() && !plan.SnatCreate.IsUnknown() && !state.SnatCreate.IsNull() && !state.SnatCreate.IsUnknown() { - if plan.SnatCreate.ValueBool() != state.SnatCreate.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.InternalPortAccess.IsNull() != state.InternalPortAccess.IsNull() || plan.InternalPortAccess.IsUnknown() != state.InternalPortAccess.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.InternalPortAccess.IsNull() && !plan.InternalPortAccess.IsUnknown() && !state.InternalPortAccess.IsNull() && !state.InternalPortAccess.IsUnknown() { - if !strings.EqualFold(plan.InternalPortAccess.ValueString(), state.InternalPortAccess.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.InternalAddrAccess.IsNull() != state.InternalAddrAccess.IsNull() || plan.InternalAddrAccess.IsUnknown() != state.InternalAddrAccess.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.InternalAddrAccess.IsNull() && !plan.InternalAddrAccess.IsUnknown() && !state.InternalAddrAccess.IsNull() && !state.InternalAddrAccess.IsUnknown() { - if !strings.EqualFold(plan.InternalAddrAccess.ValueString(), state.InternalAddrAccess.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 627: resources_core.FormatString(plan.ServiceUid), - 628: resources_core.FormatString(plan.IpSpaceName), - 629: resources_core.FormatBool(plan.DnatCreate), - 630: resources_core.FormatBool(plan.SnatCreate), - 631: resources_core.FormatString(plan.InternalPortAccess), - 632: resources_core.FormatString(plan.InternalAddrAccess), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 25, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "dnatCreate", Field: "DnatCreate", Type: "bool"}, - {Code: "fromServiceCloudEdgeName", Field: "FromServiceCloudEdgeName", Type: "string"}, - {Code: "fromServiceCloudEdgeScope", Field: "FromServiceCloudEdgeScope", Type: "string"}, - {Code: "fromServiceCloudOrgName", Field: "FromServiceCloudOrgName", Type: "string"}, - {Code: "fromServiceCloudVdcName", Field: "FromServiceCloudVdcName", Type: "string"}, - {Code: "fromServiceCloudVmwareUrl", Field: "FromServiceCloudVmwareUrl", Type: "string"}, - {Code: "fromServiceNamespace", Field: "FromServiceNamespace", Type: "string"}, - {Code: "fromServiceVdcGroupName", Field: "FromServiceVdcGroupName", Type: "string"}, - {Code: "internalAddrAccess", Field: "InternalAddrAccess", Type: "string"}, - {Code: "internalPortAccess", Field: "InternalPortAccess", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - {Code: "serviceUid", Field: "ServiceUid", Type: "string"}, - {Code: "snatCreate", Field: "SnatCreate", Type: "bool"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcexternalipResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcexternalipModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcexternalipResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcexternalipResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/26_vapp_resource.go b/generated/test/go/26_vapp_resource.go deleted file mode 100644 index c67b9f1..0000000 --- a/generated/test/go/26_vapp_resource.go +++ /dev/null @@ -1,576 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vapp -// Service ID: 26 - -var _ resource.Resource = &VappResource{} -var _ resource.ResourceWithModifyPlan = &VappResource{} -var _ resource.ResourceWithImportState = &VappResource{} - -type VappResource struct { - client *core.UniversalClient -} - -type VappModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - NsxtUid types.String `tfsdk:"nsxt_uid"` - VappName types.String `tfsdk:"vapp_name"` - VdcUid types.String `tfsdk:"vdc_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVappResource() resource.Resource { - return &VappResource{} -} - -func (r *VappResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vapp" -} - -func (r *VappResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "nsxt_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UUID Услуги `Сетевой шлюз периметра (Edge)` Не изменяется после создания."}, - "vapp_name": schema.StringAttribute{Required: true, MarkdownDescription: "Уникальное в рамках организации Не изменяется после создания."}, - "vdc_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UUID Услуги `Виртуальный датацентр (vDC)` Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VappResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VappModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.NsxtUid.ValueString(), state.NsxtUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить nsxt_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappName.IsNull() && !plan.VappName.IsUnknown() && !state.VappName.IsNull() && !state.VappName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VappName.ValueString(), state.VappName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vapp_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VdcUid.ValueString(), state.VdcUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.NsxtUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if config.NsxtUid.IsUnknown() { - return - } - if config.VappName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - if config.VappName.IsUnknown() { - return - } - if config.VdcUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if config.VdcUid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.NsxtUid.IsNull() && !config.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, config.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != config.NsxtUid.ValueString() { - config.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 190: resources_core.FormatString(config.NsxtUid), - 191: resources_core.FormatString(config.VappName), - 623: resources_core.FormatString(config.VdcUid), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 26, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VappResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.NsxtUid.IsNull() || data.NsxtUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "nsxt_uid is required.") - return - } - if data.VappName.IsNull() || data.VappName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_name is required.") - return - } - if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalNsxtUid := data.NsxtUid - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalVdcUid := data.VdcUid - if !data.NsxtUid.IsNull() && !data.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, data.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedNsxtUid != "" && resolvedNsxtUid != data.NsxtUid.ValueString() { - data.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 26, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 190: resources_core.FormatString(data.NsxtUid), - 191: resources_core.FormatString(data.VappName), - 623: resources_core.FormatString(data.VdcUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 26, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 26, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalNsxtUid.IsNull() && !originalNsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - if strings.EqualFold(state.NsxtUid.ValueString(), originalNsxtUid.ValueString()) { - state.NsxtUid = originalNsxtUid - } - } - if !originalVdcUid.IsNull() && !originalVdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if strings.EqualFold(state.VdcUid.ValueString(), originalVdcUid.ValueString()) { - state.VdcUid = originalVdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VappResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 26, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.NsxtUid.IsNull() && !newState.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, newState.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != newState.NsxtUid.ValueString() { - newState.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() && !newState.NsxtUid.IsNull() && !newState.NsxtUid.IsUnknown() { - if strings.EqualFold(newState.NsxtUid.ValueString(), state.NsxtUid.ValueString()) { - newState.NsxtUid = state.NsxtUid - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() && !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - if strings.EqualFold(newState.VdcUid.ValueString(), state.VdcUid.ValueString()) { - newState.VdcUid = state.VdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VappResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VappModel - var state VappModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 26, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "nsxtUid", Field: "NsxtUid", Type: "string"}, - {Code: "vappName", Field: "VappName", Type: "string"}, - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - resolvedNsxtUid, err := r.client.ResolveRefSvcParamValue(ctx, 22, state.NsxtUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve nsxt_uid", err.Error()) - } else if resolvedNsxtUid != "" && resolvedNsxtUid != state.NsxtUid.ValueString() { - state.NsxtUid = types.StringValue(resolvedNsxtUid) - } - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.NsxtUid.IsNull() && !plan.NsxtUid.IsUnknown() && !state.NsxtUid.IsNull() && !state.NsxtUid.IsUnknown() { - if strings.EqualFold(state.NsxtUid.ValueString(), plan.NsxtUid.ValueString()) { - state.NsxtUid = plan.NsxtUid - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if strings.EqualFold(state.VdcUid.ValueString(), plan.VdcUid.ValueString()) { - state.VdcUid = plan.VdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VappResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VappModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VappResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VappResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/27_vc_vm_v2_resource.go b/generated/test/go/27_vc_vm_v2_resource.go deleted file mode 100644 index de78745..0000000 --- a/generated/test/go/27_vc_vm_v2_resource.go +++ /dev/null @@ -1,345 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm_v2 -// Service ID: 27 - -var _ resource.Resource = &VcVmV2Resource{} -var _ resource.ResourceWithModifyPlan = &VcVmV2Resource{} -var _ resource.ResourceWithImportState = &VcVmV2Resource{} - -type VcVmV2Resource struct { - client *core.UniversalClient -} - -type VcVmV2Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - ServerListJson types.String `tfsdk:"server_list_json"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVmV2Resource() resource.Resource { - return &VcVmV2Resource{} -} - -func (r *VcVmV2Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm_v2" -} - -func (r *VcVmV2Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "server_list_json": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[{}]"), MarkdownDescription: "Необходимо изменить vappUid и ipSpaceName
Пример конфигурации взять по ссылке ниже

Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2)", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmV2Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVmV2Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVmV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVmV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 301: resources_core.FormatString(config.ServerListJson), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 27, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVmV2Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVmV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 27, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 301: resources_core.FormatString(data.ServerListJson), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 27, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 27, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "serverListJson", Field: "ServerListJson", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV2Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 27, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "serverListJson", Field: "ServerListJson", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVmV2Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmV2Model - var state VcVmV2Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ServerListJson.IsNull() != state.ServerListJson.IsNull() || plan.ServerListJson.IsUnknown() != state.ServerListJson.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ServerListJson.IsNull() && !plan.ServerListJson.IsUnknown() && !state.ServerListJson.IsNull() && !state.ServerListJson.IsUnknown() { - if !strings.EqualFold(plan.ServerListJson.ValueString(), state.ServerListJson.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 302: resources_core.FormatString(plan.ServerListJson), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 27, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "serverListJson", Field: "ServerListJson", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV2Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVmV2Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVmV2Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVmV2Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/28_vc_vm_v3_resource.go b/generated/test/go/28_vc_vm_v3_resource.go deleted file mode 100644 index 9145c69..0000000 --- a/generated/test/go/28_vc_vm_v3_resource.go +++ /dev/null @@ -1,692 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vm_v3 -// Service ID: 28 - -var _ resource.Resource = &VcVmV3Resource{} -var _ resource.ResourceWithModifyPlan = &VcVmV3Resource{} -var _ resource.ResourceWithImportState = &VcVmV3Resource{} - -type VcVmV3Resource struct { - client *core.UniversalClient -} - -type VcVmV3Model struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - // --- Redeploy support (ARCHITECTURE.md) --- - // git_revision: при изменении вызывает redeploy вместо modify. - // Опциональное поле — если не задано, modify работает как обычно. - GitRevision types.String `tfsdk:"git_revision"` - AccessIpList types.String `tfsdk:"access_ip_list"` - AccessPortList types.String `tfsdk:"access_port_list"` - CloudInit types.String `tfsdk:"cloud_init"` - ImageVm types.String `tfsdk:"image_vm"` - IpSpaceName types.String `tfsdk:"ip_space_name"` - UserLogin types.String `tfsdk:"user_login"` - UserPublicKey types.String `tfsdk:"user_public_key"` - VappUid types.String `tfsdk:"vapp_uid"` - VmCpu types.Int64 `tfsdk:"vm_cpu"` - VmDisk types.Int64 `tfsdk:"vm_disk"` - VmName types.String `tfsdk:"vm_name"` - VmRam types.Int64 `tfsdk:"vm_ram"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVmV3Resource() resource.Resource { - return &VcVmV3Resource{} -} - -func (r *VcVmV3Resource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vm_v3" -} - -func (r *VcVmV3Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_ip_list": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"]", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "access_port_list": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[\"22\"]"), MarkdownDescription: "По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX"}, - "cloud_init": schema.StringAttribute{Optional: true, MarkdownDescription: "Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. Не изменяется после создания."}, - "image_vm": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "ip_space_name": schema.StringAttribute{Required: true}, - "user_login": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("myuser"), MarkdownDescription: "Учётка SSH Не изменяется после создания."}, - "user_public_key": schema.StringAttribute{Required: true, MarkdownDescription: "Публичная часть SSH-Ключа для пользователя Не изменяется после создания."}, - "vapp_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UI display_name for service_id=26 (mapped to UUID in core) Не изменяется после создания."}, - "vm_cpu": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "шт"}, - "vm_disk": schema.Int64Attribute{Optional: true, MarkdownDescription: "Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму"}, - "vm_name": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Не изменяется после создания."}, - "vm_ram": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Gb"}, - // --- Redeploy support (ARCHITECTURE.md) --- - // При изменении git_revision вызывается redeploy вместо modify. - // Если не задано — modify работает без изменений. - "git_revision": schema.StringAttribute{Optional: true, MarkdownDescription: "Git revision (commit hash/tag). Changing this triggers redeploy instead of modify."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVmV3Resource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVmV3Model - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.CloudInit.IsNull() && !plan.CloudInit.IsUnknown() && !state.CloudInit.IsNull() && !state.CloudInit.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.CloudInit.ValueString(), state.CloudInit.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить cloud_init", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ImageVm.IsNull() && !plan.ImageVm.IsUnknown() && !state.ImageVm.IsNull() && !state.ImageVm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ImageVm.ValueString(), state.ImageVm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить image_vm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserLogin.IsNull() && !plan.UserLogin.IsUnknown() && !state.UserLogin.IsNull() && !state.UserLogin.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.UserLogin.ValueString(), state.UserLogin.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить user_login", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.UserPublicKey.IsNull() && !plan.UserPublicKey.IsUnknown() && !state.UserPublicKey.IsNull() && !state.UserPublicKey.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.UserPublicKey.ValueString(), state.UserPublicKey.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить user_public_key", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VappUid.ValueString(), state.VappUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vapp_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.VmName.IsNull() && !plan.VmName.IsUnknown() && !state.VmName.IsNull() && !state.VmName.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VmName.ValueString(), state.VmName.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vm_name", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ImageVm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.") - return - } - if config.ImageVm.IsUnknown() { - return - } - if config.IpSpaceName.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if config.IpSpaceName.IsUnknown() { - return - } - if config.UserPublicKey.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.") - return - } - if config.UserPublicKey.IsUnknown() { - return - } - if config.VappUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - if config.VappUid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VappUid.IsNull() && !config.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, config.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != config.VappUid.ValueString() { - config.VappUid = types.StringValue(resolvedVappUid) - } - } - params := map[int]string{ - 407: resources_core.FormatString(config.VappUid), - 408: resources_core.FormatString(config.VmName), - 409: resources_core.FormatInt64(config.VmCpu), - 410: resources_core.FormatInt64(config.VmRam), - 411: resources_core.FormatInt64(config.VmDisk), - 412: resources_core.FormatString(config.IpSpaceName), - 413: resources_core.FormatString(config.AccessIpList), - 414: resources_core.FormatString(config.ImageVm), - 415: resources_core.FormatString(config.CloudInit), - 416: resources_core.FormatString(config.UserLogin), - 417: resources_core.FormatString(config.UserPublicKey), - 448: resources_core.FormatString(config.AccessPortList), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 28, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVmV3Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ImageVm.IsNull() || data.ImageVm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "image_vm is required.") - return - } - if data.IpSpaceName.IsNull() || data.IpSpaceName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "ip_space_name is required.") - return - } - if data.UserPublicKey.IsNull() || data.UserPublicKey.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "user_public_key is required.") - return - } - if data.VappUid.IsNull() || data.VappUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vapp_uid is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalVappUid := data.VappUid - if !data.VappUid.IsNull() && !data.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, data.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVappUid != "" && resolvedVappUid != data.VappUid.ValueString() { - data.VappUid = types.StringValue(resolvedVappUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 28, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 407: resources_core.FormatString(data.VappUid), - 408: resources_core.FormatString(data.VmName), - 409: resources_core.FormatInt64(data.VmCpu), - 410: resources_core.FormatInt64(data.VmRam), - 411: resources_core.FormatInt64(data.VmDisk), - 412: resources_core.FormatString(data.IpSpaceName), - 413: resources_core.FormatString(data.AccessIpList), - 414: resources_core.FormatString(data.ImageVm), - 415: resources_core.FormatString(data.CloudInit), - 416: resources_core.FormatString(data.UserLogin), - 417: resources_core.FormatString(data.UserPublicKey), - 448: resources_core.FormatString(data.AccessPortList), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 28, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 28, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalVappUid.IsNull() && !originalVappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - if strings.EqualFold(state.VappUid.ValueString(), originalVappUid.ValueString()) { - state.VappUid = originalVappUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV3Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 28, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VappUid.IsNull() && !newState.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, newState.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != newState.VappUid.ValueString() { - newState.VappUid = types.StringValue(resolvedVappUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() && !newState.VappUid.IsNull() && !newState.VappUid.IsUnknown() { - if strings.EqualFold(newState.VappUid.ValueString(), state.VappUid.ValueString()) { - newState.VappUid = state.VappUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVmV3Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVmV3Model - var state VcVmV3Model - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.VmCpu.IsNull() != state.VmCpu.IsNull() || plan.VmCpu.IsUnknown() != state.VmCpu.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmCpu.IsNull() && !plan.VmCpu.IsUnknown() && !state.VmCpu.IsNull() && !state.VmCpu.IsUnknown() { - if plan.VmCpu.ValueInt64() != state.VmCpu.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmRam.IsNull() != state.VmRam.IsNull() || plan.VmRam.IsUnknown() != state.VmRam.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmRam.IsNull() && !plan.VmRam.IsUnknown() && !state.VmRam.IsNull() && !state.VmRam.IsUnknown() { - if plan.VmRam.ValueInt64() != state.VmRam.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.VmDisk.IsNull() != state.VmDisk.IsNull() || plan.VmDisk.IsUnknown() != state.VmDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.VmDisk.IsNull() && !plan.VmDisk.IsUnknown() && !state.VmDisk.IsNull() && !state.VmDisk.IsUnknown() { - if plan.VmDisk.ValueInt64() != state.VmDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceName.IsNull() != state.IpSpaceName.IsNull() || plan.IpSpaceName.IsUnknown() != state.IpSpaceName.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceName.IsNull() && !plan.IpSpaceName.IsUnknown() && !state.IpSpaceName.IsNull() && !state.IpSpaceName.IsUnknown() { - if !strings.EqualFold(plan.IpSpaceName.ValueString(), state.IpSpaceName.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessIpList.IsNull() != state.AccessIpList.IsNull() || plan.AccessIpList.IsUnknown() != state.AccessIpList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessIpList.IsNull() && !plan.AccessIpList.IsUnknown() && !state.AccessIpList.IsNull() && !state.AccessIpList.IsUnknown() { - if !strings.EqualFold(plan.AccessIpList.ValueString(), state.AccessIpList.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessPortList.IsNull() != state.AccessPortList.IsNull() || plan.AccessPortList.IsUnknown() != state.AccessPortList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessPortList.IsNull() && !plan.AccessPortList.IsUnknown() && !state.AccessPortList.IsNull() && !state.AccessPortList.IsUnknown() { - if !strings.EqualFold(plan.AccessPortList.ValueString(), state.AccessPortList.ValueString()) { - hasServiceParamChanges = true - } - } - } - // --- Redeploy support (ARCHITECTURE.md) --- - // Проверяем изменился ли git_revision. - // Если да — вызываем redeploy вместо modify. - // git_revision = "" (не задано) → обычный modify. - redeployRequested := false - if !plan.GitRevision.IsNull() && !plan.GitRevision.IsUnknown() { - if state.GitRevision.IsNull() || state.GitRevision.IsUnknown() || plan.GitRevision.ValueString() != state.GitRevision.ValueString() { - redeployRequested = true - } - } - - if !hasServiceParamChanges && !redeployRequested { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - // --- Redeploy support (ARCHITECTURE.md) --- - if redeployRequested { - // Вызываем redeploy — пустой params (операция не требует CFS-параметров) - if err := r.client.RunRedeployOperation(ctx, instanceID.ValueString(), operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } else { - params := map[int]string{ - 493: resources_core.FormatInt64(plan.VmCpu), - 494: resources_core.FormatInt64(plan.VmRam), - 495: resources_core.FormatInt64(plan.VmDisk), - 496: resources_core.FormatString(plan.IpSpaceName), - 497: resources_core.FormatString(plan.AccessIpList), - 498: resources_core.FormatString(plan.AccessPortList), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 28, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessIpList", Field: "AccessIpList", Type: "string"}, - {Code: "accessPortList", Field: "AccessPortList", Type: "string"}, - {Code: "cloudInit", Field: "CloudInit", Type: "string"}, - {Code: "imageVm", Field: "ImageVm", Type: "string"}, - {Code: "ipSpaceName", Field: "IpSpaceName", Type: "string"}, - {Code: "userLogin", Field: "UserLogin", Type: "string"}, - {Code: "userPublicKey", Field: "UserPublicKey", Type: "string"}, - {Code: "vappUid", Field: "VappUid", Type: "string"}, - {Code: "vmCpu", Field: "VmCpu", Type: "int64"}, - {Code: "vmDisk", Field: "VmDisk", Type: "int64"}, - {Code: "vmName", Field: "VmName", Type: "string"}, - {Code: "vmRam", Field: "VmRam", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - resolvedVappUid, err := r.client.ResolveRefSvcParamValue(ctx, 26, state.VappUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vapp_uid", err.Error()) - } else if resolvedVappUid != "" && resolvedVappUid != state.VappUid.ValueString() { - state.VappUid = types.StringValue(resolvedVappUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.VappUid.IsNull() && !plan.VappUid.IsUnknown() && !state.VappUid.IsNull() && !state.VappUid.IsUnknown() { - if strings.EqualFold(state.VappUid.ValueString(), plan.VappUid.ValueString()) { - state.VappUid = plan.VappUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVmV3Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVmV3Model - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVmV3Resource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVmV3Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/29_vc_vdc_group_resource.go b/generated/test/go/29_vc_vdc_group_resource.go deleted file mode 100644 index aebdf49..0000000 --- a/generated/test/go/29_vc_vdc_group_resource.go +++ /dev/null @@ -1,444 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Service ID: 29 - -var _ resource.Resource = &VcVdcGroupResource{} -var _ resource.ResourceWithModifyPlan = &VcVdcGroupResource{} -var _ resource.ResourceWithImportState = &VcVdcGroupResource{} - -type VcVdcGroupResource struct { - client *core.UniversalClient -} - -type VcVdcGroupModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - VdcUid types.String `tfsdk:"vdc_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVcVdcGroupResource() resource.Resource { - return &VcVdcGroupResource{} -} - -func (r *VcVdcGroupResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group" -} - -func (r *VcVdcGroupResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "vdc_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UI display_name for service_id=21 (mapped to UUID in core) Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VcVdcGroupModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.VdcUid.ValueString(), state.VdcUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить vdc_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.VdcUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - if config.VdcUid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.VdcUid.IsNull() && !config.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, config.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != config.VdcUid.ValueString() { - config.VdcUid = types.StringValue(resolvedVdcUid) - } - } - params := map[int]string{ - 618: resources_core.FormatString(config.VdcUid), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 29, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VcVdcGroupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.VdcUid.IsNull() || data.VdcUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "vdc_uid is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalVdcUid := data.VdcUid - if !data.VdcUid.IsNull() && !data.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, data.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedVdcUid != "" && resolvedVdcUid != data.VdcUid.ValueString() { - data.VdcUid = types.StringValue(resolvedVdcUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 29, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 618: resources_core.FormatString(data.VdcUid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 29, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 29, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalVdcUid.IsNull() && !originalVdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if strings.EqualFold(state.VdcUid.ValueString(), originalVdcUid.ValueString()) { - state.VdcUid = originalVdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 29, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, newState.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != newState.VdcUid.ValueString() { - newState.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() && !newState.VdcUid.IsNull() && !newState.VdcUid.IsUnknown() { - if strings.EqualFold(newState.VdcUid.ValueString(), state.VdcUid.ValueString()) { - newState.VdcUid = state.VdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VcVdcGroupResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupModel - var state VcVdcGroupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 29, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "vdcUid", Field: "VdcUid", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - resolvedVdcUid, err := r.client.ResolveRefSvcParamValue(ctx, 21, state.VdcUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve vdc_uid", err.Error()) - } else if resolvedVdcUid != "" && resolvedVdcUid != state.VdcUid.ValueString() { - state.VdcUid = types.StringValue(resolvedVdcUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.VdcUid.IsNull() && !plan.VdcUid.IsUnknown() && !state.VdcUid.IsNull() && !state.VdcUid.IsUnknown() { - if strings.EqualFold(state.VdcUid.ValueString(), plan.VdcUid.ValueString()) { - state.VdcUid = plan.VdcUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVdcGroupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VcVdcGroupResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VcVdcGroupResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/29_vc_vdc_group_vdc_resource.go b/generated/test/go/29_vc_vdc_group_vdc_resource.go deleted file mode 100644 index 8524d4d..0000000 --- a/generated/test/go/29_vc_vdc_group_vdc_resource.go +++ /dev/null @@ -1,330 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vc_vdc_group -// Subresource: vdc - -var _ resource.Resource = &VcVdcGroupVdcResource{} - -// VcVdcGroupVdcResource manages a subresource via operations. -type VcVdcGroupVdcResource struct { - client *core.UniversalClient -} - -type VcVdcGroupVdcModel struct { - ID types.String `tfsdk:"id"` - VcVdcGroupID types.String `tfsdk:"vc_vdc_group_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewVcVdcGroupVdcResource() resource.Resource { - return &VcVdcGroupVdcResource{} -} - -func (r *VcVdcGroupVdcResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vc_vdc_group_vdc" -} - -func (r *VcVdcGroupVdcResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "vc_vdc_group_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VcVdcGroupVdcResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan VcVdcGroupVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{} - identityCodes := []string{} - listKey, idKey := resources_core.ResolveSubresourceStateKeys("vdc", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "vdc", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{}) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "vdc", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "vdc", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "vdc", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupVdcResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VcVdcGroupVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VcVdcGroupVdcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VcVdcGroupVdcModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state VcVdcGroupVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.VcVdcGroupID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "vdc", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *VcVdcGroupVdcResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VcVdcGroupVdcModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - return - } - - instanceUID := strings.TrimSpace(state.VcVdcGroupID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{} - identityCodes := []string{} - listKey, idKey := resources_core.ResolveSubresourceStateKeys("vdc", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{}) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *VcVdcGroupVdcResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/2_template_resource.go b/generated/test/go/2_template_resource.go deleted file mode 100644 index f360e1a..0000000 --- a/generated/test/go/2_template_resource.go +++ /dev/null @@ -1,410 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: template -// Service ID: 2 - -var _ resource.Resource = &TemplateResource{} -var _ resource.ResourceWithModifyPlan = &TemplateResource{} -var _ resource.ResourceWithImportState = &TemplateResource{} - -type TemplateResource struct { - client *core.UniversalClient -} - -type TemplateModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewTemplateResource() resource.Resource { - return &TemplateResource{} -} - -func (r *TemplateResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_template" -} - -func (r *TemplateResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *TemplateResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *TemplateModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 813: resources_core.FormatString(config.ClusterConfiguration), - 814: resources_core.FormatString(config.StartupConfiguration), - 815: resources_core.FormatString(config.AccessConfiguration), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 2, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *TemplateResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 2, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 813: resources_core.FormatString(data.ClusterConfiguration), - 814: resources_core.FormatString(data.StartupConfiguration), - 815: resources_core.FormatString(data.AccessConfiguration), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 2, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 2, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TemplateResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 2, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *TemplateResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan TemplateModel - var state TemplateModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessConfiguration.IsNull() != state.AccessConfiguration.IsNull() || plan.AccessConfiguration.IsUnknown() != state.AccessConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 816: resources_core.FormatString(plan.ClusterConfiguration), - 817: resources_core.FormatString(plan.AccessConfiguration), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 2, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *TemplateResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state TemplateModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *TemplateResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *TemplateResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/32_vmpostgre_resource.go b/generated/test/go/32_vmpostgre_resource.go deleted file mode 100644 index 2c99ecc..0000000 --- a/generated/test/go/32_vmpostgre_resource.go +++ /dev/null @@ -1,317 +0,0 @@ -package resources_gen - -import ( - "context" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: vmpostgre -// Service ID: 32 - -var _ resource.Resource = &VmpostgreResource{} -var _ resource.ResourceWithModifyPlan = &VmpostgreResource{} -var _ resource.ResourceWithImportState = &VmpostgreResource{} - -type VmpostgreResource struct { - client *core.UniversalClient -} - -type VmpostgreModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewVmpostgreResource() resource.Resource { - return &VmpostgreResource{} -} - -func (r *VmpostgreResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_vmpostgre" -} - -func (r *VmpostgreResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *VmpostgreResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *VmpostgreModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *VmpostgreModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan VmpostgreModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{} - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 32, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *VmpostgreResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data VmpostgreModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 32, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{} - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 32, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 32, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VmpostgreResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state VmpostgreModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 32, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *VmpostgreResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan VmpostgreModel - var state VmpostgreModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 32, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *VmpostgreResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state VmpostgreModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *VmpostgreResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *VmpostgreResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/50_nextcloud_backup_resource.go b/generated/test/go/50_nextcloud_backup_resource.go deleted file mode 100644 index 71bb43e..0000000 --- a/generated/test/go/50_nextcloud_backup_resource.go +++ /dev/null @@ -1,348 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nextcloud -// Subresource: backup - -var _ resource.Resource = &NextcloudBackupResource{} - -// NextcloudBackupResource manages a subresource via operations. -type NextcloudBackupResource struct { - client *core.UniversalClient -} - -type NextcloudBackupModel struct { - ID types.String `tfsdk:"id"` - NextcloudID types.String `tfsdk:"nextcloud_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` -} - -func NewNextcloudBackupResource() resource.Resource { - return &NextcloudBackupResource{} -} - -func (r *NextcloudBackupResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nextcloud_backup" -} - -func (r *NextcloudBackupResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "nextcloud_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NextcloudBackupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan NextcloudBackupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.StartupConfiguration.IsNull() || plan.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - instanceUID := strings.TrimSpace(plan.NextcloudID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "startupConfiguration": resources_core.FormatString(plan.StartupConfiguration), - } - identityCodes := []string{ - "startupConfiguration", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("backup", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "startupConfiguration": resources_core.FormatString(plan.StartupConfiguration), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_backup", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_backup", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NextcloudBackupResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NextcloudBackupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudBackupResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NextcloudBackupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state NextcloudBackupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.NextcloudID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "startupConfiguration": resources_core.FormatString(plan.StartupConfiguration), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *NextcloudBackupResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NextcloudBackupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - return - } - - instanceUID := strings.TrimSpace(state.NextcloudID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "startupConfiguration": resources_core.FormatString(state.StartupConfiguration), - } - identityCodes := []string{ - "startupConfiguration", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("backup", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{}) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *NextcloudBackupResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/50_nextcloud_resource.go b/generated/test/go/50_nextcloud_resource.go deleted file mode 100644 index 6068c97..0000000 --- a/generated/test/go/50_nextcloud_resource.go +++ /dev/null @@ -1,437 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nextcloud -// Service ID: 50 - -var _ resource.Resource = &NextcloudResource{} -var _ resource.ResourceWithModifyPlan = &NextcloudResource{} -var _ resource.ResourceWithImportState = &NextcloudResource{} - -type NextcloudResource struct { - client *core.UniversalClient -} - -type NextcloudModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - AppConfiguration types.String `tfsdk:"app_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNextcloudResource() resource.Resource { - return &NextcloudResource{} -} - -func (r *NextcloudResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nextcloud" -} - -func (r *NextcloudResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "app_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NextcloudResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NextcloudModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить access_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.AppConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "app_configuration is required.") - return - } - if config.AppConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 1055: resources_core.FormatString(config.StartupConfiguration), - 1056: resources_core.FormatString(config.ClusterConfiguration), - 1057: resources_core.FormatString(config.AccessConfiguration), - 1058: resources_core.FormatString(config.AppConfiguration), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 50, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NextcloudResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.AppConfiguration.IsNull() || data.AppConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "app_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 50, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 1055: resources_core.FormatString(data.StartupConfiguration), - 1056: resources_core.FormatString(data.ClusterConfiguration), - 1057: resources_core.FormatString(data.AccessConfiguration), - 1058: resources_core.FormatString(data.AppConfiguration), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 50, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 50, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 50, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NextcloudResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NextcloudModel - var state NextcloudModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppConfiguration.IsNull() != state.AppConfiguration.IsNull() || plan.AppConfiguration.IsUnknown() != state.AppConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppConfiguration.IsNull() && !plan.AppConfiguration.IsUnknown() && !state.AppConfiguration.IsNull() && !state.AppConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AppConfiguration.ValueString(), state.AppConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 1059: resources_core.FormatString(plan.ClusterConfiguration), - 1060: resources_core.FormatString(plan.AppConfiguration), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 50, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NextcloudResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NextcloudModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NextcloudResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NextcloudResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/81_superset_resource.go b/generated/test/go/81_superset_resource.go deleted file mode 100644 index 424ce42..0000000 --- a/generated/test/go/81_superset_resource.go +++ /dev/null @@ -1,442 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: superset -// Service ID: 81 - -var _ resource.Resource = &SupersetResource{} -var _ resource.ResourceWithModifyPlan = &SupersetResource{} -var _ resource.ResourceWithImportState = &SupersetResource{} - -type SupersetResource struct { - client *core.UniversalClient -} - -type SupersetModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - Emails types.String `tfsdk:"emails"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewSupersetResource() resource.Resource { - return &SupersetResource{} -} - -func (r *SupersetResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_superset" -} - -func (r *SupersetResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "emails": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("testuser1"), MarkdownDescription: "Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *SupersetResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *SupersetModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Emails.IsNull() && !plan.Emails.IsUnknown() && !state.Emails.IsNull() && !state.Emails.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Emails.ValueString(), state.Emails.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить emails", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 14: resources_core.FormatString(config.Domain), - 20: resources_core.FormatString(config.Emails), - 96: resources_core.FormatInt64(config.ResourceCPU), - 97: resources_core.FormatInt64(config.ResourceMemory), - 98: resources_core.FormatInt64(config.ResourceDisk), - 109: resources_core.FormatString(config.ResourceRealm), - 227: resources_core.FormatInt64(config.ResourceInstances), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 81, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *SupersetResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 81, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 14: resources_core.FormatString(data.Domain), - 20: resources_core.FormatString(data.Emails), - 96: resources_core.FormatInt64(data.ResourceCPU), - 97: resources_core.FormatInt64(data.ResourceMemory), - 98: resources_core.FormatInt64(data.ResourceDisk), - 109: resources_core.FormatString(data.ResourceRealm), - 227: resources_core.FormatInt64(data.ResourceInstances), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 81, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 81, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *SupersetResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 81, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *SupersetResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan SupersetModel - var state SupersetModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 81, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "emails", Field: "Emails", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *SupersetResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state SupersetModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *SupersetResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *SupersetResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/82_harbor_resource.go b/generated/test/go/82_harbor_resource.go deleted file mode 100644 index 453bfaa..0000000 --- a/generated/test/go/82_harbor_resource.go +++ /dev/null @@ -1,477 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: harbor -// Service ID: 82 - -var _ resource.Resource = &HarborResource{} -var _ resource.ResourceWithModifyPlan = &HarborResource{} -var _ resource.ResourceWithImportState = &HarborResource{} - -type HarborResource struct { - client *core.UniversalClient -} - -type HarborModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - S3Uid types.String `tfsdk:"s3_uid"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewHarborResource() resource.Resource { - return &HarborResource{} -} - -func (r *HarborResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_harbor" -} - -func (r *HarborResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "s3_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UUID экземпляра услуги S3 Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *HarborResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *HarborModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.S3Uid.IsNull() && !plan.S3Uid.IsUnknown() && !state.S3Uid.IsNull() && !state.S3Uid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.S3Uid.ValueString(), state.S3Uid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить s3_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - if config.S3Uid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - if config.S3Uid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.S3Uid.IsNull() && !config.S3Uid.IsUnknown() { - resolvedS3Uid, err := r.client.ResolveRefSvcParamValue(ctx, 12, config.S3Uid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve s3_uid", err.Error()) - } else if resolvedS3Uid != "" && resolvedS3Uid != config.S3Uid.ValueString() { - config.S3Uid = types.StringValue(resolvedS3Uid) - } - } - params := map[int]string{ - 16: resources_core.FormatString(config.Domain), - 110: resources_core.FormatString(config.ResourceRealm), - 228: resources_core.FormatInt64(config.ResourceCPU), - 229: resources_core.FormatInt64(config.ResourceMemory), - 230: resources_core.FormatInt64(config.ResourceInstances), - 231: resources_core.FormatString(config.S3Uid), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 82, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *HarborResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if data.S3Uid.IsNull() || data.S3Uid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "s3_uid is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 82, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 16: resources_core.FormatString(data.Domain), - 110: resources_core.FormatString(data.ResourceRealm), - 228: resources_core.FormatInt64(data.ResourceCPU), - 229: resources_core.FormatInt64(data.ResourceMemory), - 230: resources_core.FormatInt64(data.ResourceInstances), - 231: resources_core.FormatString(data.S3Uid), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 82, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 82, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HarborResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 82, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *HarborResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan HarborModel - var state HarborModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 822: resources_core.FormatInt64(plan.ResourceInstances), - 823: resources_core.FormatInt64(plan.ResourceCPU), - 824: resources_core.FormatInt64(plan.ResourceMemory), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 82, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HarborResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state HarborModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *HarborResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *HarborResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/88_k8s_ziti_controller_resource.go b/generated/test/go/88_k8s_ziti_controller_resource.go deleted file mode 100644 index 02b01e3..0000000 --- a/generated/test/go/88_k8s_ziti_controller_resource.go +++ /dev/null @@ -1,426 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: k8s_ziti_controller -// Service ID: 88 - -var _ resource.Resource = &K8sZitiControllerResource{} -var _ resource.ResourceWithModifyPlan = &K8sZitiControllerResource{} -var _ resource.ResourceWithImportState = &K8sZitiControllerResource{} - -type K8sZitiControllerResource struct { - client *core.UniversalClient -} - -type K8sZitiControllerModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewK8sZitiControllerResource() resource.Resource { - return &K8sZitiControllerResource{} -} - -func (r *K8sZitiControllerResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_k8s_ziti_controller" -} - -func (r *K8sZitiControllerResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(300), MarkdownDescription: "Квота ядра пода (milicores) Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *K8sZitiControllerResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *K8sZitiControllerModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 294: resources_core.FormatInt64(config.ResourceCPU), - 295: resources_core.FormatInt64(config.ResourceMemory), - 296: resources_core.FormatInt64(config.ResourceDisk), - 297: resources_core.FormatInt64(config.ResourceInstances), - 298: resources_core.FormatString(config.ResourceRealm), - 299: resources_core.FormatString(config.Domain), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 88, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *K8sZitiControllerResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 88, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 294: resources_core.FormatInt64(data.ResourceCPU), - 295: resources_core.FormatInt64(data.ResourceMemory), - 296: resources_core.FormatInt64(data.ResourceDisk), - 297: resources_core.FormatInt64(data.ResourceInstances), - 298: resources_core.FormatString(data.ResourceRealm), - 299: resources_core.FormatString(data.Domain), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 88, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 88, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sZitiControllerResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 88, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *K8sZitiControllerResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan K8sZitiControllerModel - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 88, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *K8sZitiControllerResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state K8sZitiControllerModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *K8sZitiControllerResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *K8sZitiControllerResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/89_flask_resource.go b/generated/test/go/89_flask_resource.go deleted file mode 100644 index 40a4919..0000000 --- a/generated/test/go/89_flask_resource.go +++ /dev/null @@ -1,482 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: flask -// Service ID: 89 - -var _ resource.Resource = &FlaskResource{} -var _ resource.ResourceWithModifyPlan = &FlaskResource{} -var _ resource.ResourceWithImportState = &FlaskResource{} - -type FlaskResource struct { - client *core.UniversalClient -} - -type FlaskModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - // --- Redeploy support (ARCHITECTURE.md) --- - // git_revision: при изменении вызывает redeploy вместо modify. - // Опциональное поле — если не задано, modify работает как обычно. - GitRevision types.String `tfsdk:"git_revision"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - AppConfiguration types.String `tfsdk:"app_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - JsonEnv types.String `tfsdk:"json_env"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewFlaskResource() resource.Resource { - return &FlaskResource{} -} - -func (r *FlaskResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_flask" -} - -func (r *FlaskResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "app_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{}")}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - // --- Redeploy support (ARCHITECTURE.md) --- - // При изменении git_revision вызывается redeploy вместо modify. - // Если не задано — modify работает без изменений. - "git_revision": schema.StringAttribute{Optional: true, MarkdownDescription: "Git revision (commit hash/tag). Changing this triggers redeploy instead of modify."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *FlaskResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *FlaskModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить access_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.AppConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "app_configuration is required.") - return - } - if config.AppConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 1037: resources_core.FormatString(config.StartupConfiguration), - 1038: resources_core.FormatString(config.ClusterConfiguration), - 1039: resources_core.FormatString(config.AccessConfiguration), - 1040: resources_core.FormatString(config.AppConfiguration), - 1041: resources_core.FormatString(config.JsonEnv), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 89, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *FlaskResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.AppConfiguration.IsNull() || data.AppConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "app_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 89, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 1037: resources_core.FormatString(data.StartupConfiguration), - 1038: resources_core.FormatString(data.ClusterConfiguration), - 1039: resources_core.FormatString(data.AccessConfiguration), - 1040: resources_core.FormatString(data.AppConfiguration), - 1041: resources_core.FormatString(data.JsonEnv), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 89, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 89, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *FlaskResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 89, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *FlaskResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan FlaskModel - var state FlaskModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppConfiguration.IsNull() != state.AppConfiguration.IsNull() || plan.AppConfiguration.IsUnknown() != state.AppConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppConfiguration.IsNull() && !plan.AppConfiguration.IsUnknown() && !state.AppConfiguration.IsNull() && !state.AppConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AppConfiguration.ValueString(), state.AppConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if !strings.EqualFold(plan.JsonEnv.ValueString(), state.JsonEnv.ValueString()) { - hasServiceParamChanges = true - } - } - } - // --- Redeploy support (ARCHITECTURE.md) --- - // Проверяем изменился ли git_revision. - // Если да — вызываем redeploy вместо modify. - // git_revision = "" (не задано) → обычный modify. - redeployRequested := false - if !plan.GitRevision.IsNull() && !plan.GitRevision.IsUnknown() { - if state.GitRevision.IsNull() || state.GitRevision.IsUnknown() || plan.GitRevision.ValueString() != state.GitRevision.ValueString() { - redeployRequested = true - } - } - - if !hasServiceParamChanges && !redeployRequested { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - // --- Redeploy support (ARCHITECTURE.md) --- - if redeployRequested { - // Вызываем redeploy — пустой params (операция не требует CFS-параметров) - if err := r.client.RunRedeployOperation(ctx, instanceID.ValueString(), operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } else { - params := map[int]string{ - 1042: resources_core.FormatString(plan.ClusterConfiguration), - 1043: resources_core.FormatString(plan.AppConfiguration), - 1044: resources_core.FormatString(plan.JsonEnv), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 89, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *FlaskResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state FlaskModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *FlaskResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *FlaskResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/90_postgres_backup_resource.go b/generated/test/go/90_postgres_backup_resource.go deleted file mode 100644 index 83c0223..0000000 --- a/generated/test/go/90_postgres_backup_resource.go +++ /dev/null @@ -1,330 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Subresource: backup - -var _ resource.Resource = &PostgresBackupResource{} - -// PostgresBackupResource manages a subresource via operations. -type PostgresBackupResource struct { - client *core.UniversalClient -} - -type PostgresBackupModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` -} - -func NewPostgresBackupResource() resource.Resource { - return &PostgresBackupResource{} -} - -func (r *PostgresBackupResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_backup" -} - -func (r *PostgresBackupResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "postgres_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresBackupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresBackupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{} - identityCodes := []string{} - listKey, idKey := resources_core.ResolveSubresourceStateKeys("backup", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{}) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_backup", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_backup", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresBackupResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresBackupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresBackupResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresBackupModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state PostgresBackupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{} - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "backup", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresBackupResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PostgresBackupModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - return - } - - instanceUID := strings.TrimSpace(state.PostgresID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{} - identityCodes := []string{} - listKey, idKey := resources_core.ResolveSubresourceStateKeys("backup", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{}) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *PostgresBackupResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/90_postgres_database_resource.go b/generated/test/go/90_postgres_database_resource.go deleted file mode 100644 index fe86da9..0000000 --- a/generated/test/go/90_postgres_database_resource.go +++ /dev/null @@ -1,362 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Subresource: database - -var _ resource.Resource = &PostgresDatabaseResource{} - -// PostgresDatabaseResource manages a subresource via operations. -type PostgresDatabaseResource struct { - client *core.UniversalClient -} - -type PostgresDatabaseModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DbName types.String `tfsdk:"db_name"` - DbOwner types.String `tfsdk:"db_owner"` -} - -func NewPostgresDatabaseResource() resource.Resource { - return &PostgresDatabaseResource{} -} - -func (r *PostgresDatabaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_database" -} - -func (r *PostgresDatabaseResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "postgres_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "db_name": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "db_owner": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresDatabaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.DbName.IsNull() || plan.DbName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "db_name is required.") - return - } - if plan.DbOwner.IsNull() || plan.DbOwner.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "db_owner is required.") - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - "dbOwner": resources_core.FormatString(plan.DbOwner), - } - identityCodes := []string{ - "dbName", - "dbOwner", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - "dbOwner": resources_core.FormatString(plan.DbOwner), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_database", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresDatabaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresDatabaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresDatabaseModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state PostgresDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "dbName": resources_core.FormatString(plan.DbName), - "dbOwner": resources_core.FormatString(plan.DbOwner), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "database", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresDatabaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PostgresDatabaseModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_database" == "" { - return - } - - instanceUID := strings.TrimSpace(state.PostgresID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "dbName": resources_core.FormatString(state.DbName), - "dbOwner": resources_core.FormatString(state.DbOwner), - } - identityCodes := []string{ - "dbName", - "dbOwner", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("database", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "dbName": resources_core.FormatString(state.DbName), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_database", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *PostgresDatabaseResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/90_postgres_resource.go b/generated/test/go/90_postgres_resource.go deleted file mode 100644 index 77912fd..0000000 --- a/generated/test/go/90_postgres_resource.go +++ /dev/null @@ -1,511 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Service ID: 90 - -var _ resource.Resource = &PostgresResource{} -var _ resource.ResourceWithModifyPlan = &PostgresResource{} -var _ resource.ResourceWithImportState = &PostgresResource{} - -type PostgresResource struct { - client *core.UniversalClient -} - -type PostgresModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - AutoscaleConfiguration types.String `tfsdk:"autoscale_configuration"` - BackupConfiguration types.String `tfsdk:"backup_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - PostgresConf types.String `tfsdk:"postgres_conf"` - PostgresConfiguration types.String `tfsdk:"postgres_configuration"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewPostgresResource() resource.Resource { - return &PostgresResource{} -} - -func (r *PostgresResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres" -} - -func (r *PostgresResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true}, - "autoscale_configuration": schema.StringAttribute{Required: true}, - "backup_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "postgres_conf": schema.StringAttribute{Optional: true}, - "postgres_configuration": schema.StringAttribute{Required: true}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *PostgresModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.AutoscaleConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "autoscale_configuration is required.") - return - } - if config.AutoscaleConfiguration.IsUnknown() { - return - } - if config.BackupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "backup_configuration is required.") - return - } - if config.BackupConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.PostgresConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "postgres_configuration is required.") - return - } - if config.PostgresConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 788: resources_core.FormatString(config.ClusterConfiguration), - 789: resources_core.FormatString(config.StartupConfiguration), - 790: resources_core.FormatString(config.AccessConfiguration), - 791: resources_core.FormatString(config.PostgresConfiguration), - 792: resources_core.FormatString(config.PostgresConf), - 793: resources_core.FormatString(config.BackupConfiguration), - 794: resources_core.FormatString(config.AutoscaleConfiguration), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 90, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *PostgresResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.AutoscaleConfiguration.IsNull() || data.AutoscaleConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "autoscale_configuration is required.") - return - } - if data.BackupConfiguration.IsNull() || data.BackupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "backup_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.PostgresConfiguration.IsNull() || data.PostgresConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "postgres_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 90, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 788: resources_core.FormatString(data.ClusterConfiguration), - 789: resources_core.FormatString(data.StartupConfiguration), - 790: resources_core.FormatString(data.AccessConfiguration), - 791: resources_core.FormatString(data.PostgresConfiguration), - 792: resources_core.FormatString(data.PostgresConf), - 793: resources_core.FormatString(data.BackupConfiguration), - 794: resources_core.FormatString(data.AutoscaleConfiguration), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 90, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 90, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "postgresConf", Field: "PostgresConf", Type: "string"}, - {Code: "postgresConfiguration", Field: "PostgresConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 90, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "postgresConf", Field: "PostgresConf", Type: "string"}, - {Code: "postgresConfiguration", Field: "PostgresConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *PostgresResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresModel - var state PostgresModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessConfiguration.IsNull() != state.AccessConfiguration.IsNull() || plan.AccessConfiguration.IsUnknown() != state.AccessConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.PostgresConfiguration.IsNull() != state.PostgresConfiguration.IsNull() || plan.PostgresConfiguration.IsUnknown() != state.PostgresConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.PostgresConfiguration.IsNull() && !plan.PostgresConfiguration.IsUnknown() && !state.PostgresConfiguration.IsNull() && !state.PostgresConfiguration.IsUnknown() { - if !strings.EqualFold(plan.PostgresConfiguration.ValueString(), state.PostgresConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.PostgresConf.IsNull() != state.PostgresConf.IsNull() || plan.PostgresConf.IsUnknown() != state.PostgresConf.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.PostgresConf.IsNull() && !plan.PostgresConf.IsUnknown() && !state.PostgresConf.IsNull() && !state.PostgresConf.IsUnknown() { - if !strings.EqualFold(plan.PostgresConf.ValueString(), state.PostgresConf.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.BackupConfiguration.IsNull() != state.BackupConfiguration.IsNull() || plan.BackupConfiguration.IsUnknown() != state.BackupConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.BackupConfiguration.IsNull() && !plan.BackupConfiguration.IsUnknown() && !state.BackupConfiguration.IsNull() && !state.BackupConfiguration.IsUnknown() { - if !strings.EqualFold(plan.BackupConfiguration.ValueString(), state.BackupConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AutoscaleConfiguration.IsNull() != state.AutoscaleConfiguration.IsNull() || plan.AutoscaleConfiguration.IsUnknown() != state.AutoscaleConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AutoscaleConfiguration.IsNull() && !plan.AutoscaleConfiguration.IsUnknown() && !state.AutoscaleConfiguration.IsNull() && !state.AutoscaleConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AutoscaleConfiguration.ValueString(), state.AutoscaleConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 795: resources_core.FormatString(plan.ClusterConfiguration), - 796: resources_core.FormatString(plan.AccessConfiguration), - 797: resources_core.FormatString(plan.PostgresConfiguration), - 798: resources_core.FormatString(plan.PostgresConf), - 799: resources_core.FormatString(plan.BackupConfiguration), - 800: resources_core.FormatString(plan.AutoscaleConfiguration), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 90, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "autoscaleConfiguration", Field: "AutoscaleConfiguration", Type: "string"}, - {Code: "backupConfiguration", Field: "BackupConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "postgresConf", Field: "PostgresConf", Type: "string"}, - {Code: "postgresConfiguration", Field: "PostgresConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PostgresModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *PostgresResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *PostgresResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/90_postgres_user_resource.go b/generated/test/go/90_postgres_user_resource.go deleted file mode 100644 index 2122df2..0000000 --- a/generated/test/go/90_postgres_user_resource.go +++ /dev/null @@ -1,362 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: postgres -// Subresource: user - -var _ resource.Resource = &PostgresUserResource{} - -// PostgresUserResource manages a subresource via operations. -type PostgresUserResource struct { - client *core.UniversalClient -} - -type PostgresUserModel struct { - ID types.String `tfsdk:"id"` - PostgresID types.String `tfsdk:"postgres_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Role types.String `tfsdk:"role"` - Username types.String `tfsdk:"username"` -} - -func NewPostgresUserResource() resource.Resource { - return &PostgresUserResource{} -} - -func (r *PostgresUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_postgres_user" -} - -func (r *PostgresUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "postgres_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "role": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать роль из списка Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания. Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PostgresUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan PostgresUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.Role.IsNull() || plan.Role.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "role is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "role": resources_core.FormatString(plan.Role), - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "role", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "role": resources_core.FormatString(plan.Role), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PostgresUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PostgresUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PostgresUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "" == "" { - var state PostgresUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.PostgresID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{}) - - idParams := map[string]string{ - "role": resources_core.FormatString(plan.Role), - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *PostgresUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PostgresUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.PostgresID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "role": resources_core.FormatString(state.Role), - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "role", - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *PostgresUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/91_redis_resource.go b/generated/test/go/91_redis_resource.go deleted file mode 100644 index 0ad1e71..0000000 --- a/generated/test/go/91_redis_resource.go +++ /dev/null @@ -1,410 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: redis -// Service ID: 91 - -var _ resource.Resource = &RedisResource{} -var _ resource.ResourceWithModifyPlan = &RedisResource{} -var _ resource.ResourceWithImportState = &RedisResource{} - -type RedisResource struct { - client *core.UniversalClient -} - -type RedisModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewRedisResource() resource.Resource { - return &RedisResource{} -} - -func (r *RedisResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_redis" -} - -func (r *RedisResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *RedisResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *RedisModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 1061: resources_core.FormatString(config.StartupConfiguration), - 1062: resources_core.FormatString(config.ClusterConfiguration), - 1063: resources_core.FormatString(config.AccessConfiguration), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 91, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *RedisResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 91, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 1061: resources_core.FormatString(data.StartupConfiguration), - 1062: resources_core.FormatString(data.ClusterConfiguration), - 1063: resources_core.FormatString(data.AccessConfiguration), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 91, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 91, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RedisResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 91, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *RedisResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan RedisModel - var state RedisModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AccessConfiguration.IsNull() != state.AccessConfiguration.IsNull() || plan.AccessConfiguration.IsUnknown() != state.AccessConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 1064: resources_core.FormatString(plan.ClusterConfiguration), - 1065: resources_core.FormatString(plan.AccessConfiguration), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 91, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RedisResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state RedisModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *RedisResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *RedisResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/92_mongodb_resource.go b/generated/test/go/92_mongodb_resource.go deleted file mode 100644 index 7dd5671..0000000 --- a/generated/test/go/92_mongodb_resource.go +++ /dev/null @@ -1,501 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mongodb -// Service ID: 92 - -var _ resource.Resource = &MongodbResource{} -var _ resource.ResourceWithModifyPlan = &MongodbResource{} -var _ resource.ResourceWithImportState = &MongodbResource{} - -type MongodbResource struct { - client *core.UniversalClient -} - -type MongodbModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - MasterAccessList types.String `tfsdk:"master_access_list"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewMongodbResource() resource.Resource { - return &MongodbResource{} -} - -func (r *MongodbResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mongodb" -} - -func (r *MongodbResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`"}, - "master_access_list": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("[]"), MarkdownDescription: "Список IP-адресов, с которых разрешён доступ. Если оставить пустым — доступ открыт всем.", PlanModifiers: []planmodifier.String{resources_core.JsonNormalize()}}, - "resource_c_p_u": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `1000`"}, - "resource_disk": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `20`"}, - "resource_instances": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2`"}, - "resource_memory": schema.Int64Attribute{Required: true, MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MongodbResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *MongodbModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceCPU.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if config.ResourceCPU.IsUnknown() { - return - } - if config.ResourceDisk.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if config.ResourceDisk.IsUnknown() { - return - } - if config.ResourceInstances.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if config.ResourceInstances.IsUnknown() { - return - } - if config.ResourceMemory.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if config.ResourceMemory.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 487: resources_core.FormatInt64(config.ResourceInstances), - 588: resources_core.FormatInt64(config.ResourceMemory), - 589: resources_core.FormatInt64(config.ResourceCPU), - 590: resources_core.FormatInt64(config.ResourceDisk), - 595: resources_core.FormatString(config.ResourceRealm), - 646: resources_core.FormatString(config.IpSpaceNameMaster), - 889: resources_core.FormatString(config.MasterAccessList), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 92, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *MongodbResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceCPU.IsNull() || data.ResourceCPU.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_c_p_u is required.") - return - } - if data.ResourceDisk.IsNull() || data.ResourceDisk.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_disk is required.") - return - } - if data.ResourceInstances.IsNull() || data.ResourceInstances.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_instances is required.") - return - } - if data.ResourceMemory.IsNull() || data.ResourceMemory.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_memory is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 92, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 487: resources_core.FormatInt64(data.ResourceInstances), - 588: resources_core.FormatInt64(data.ResourceMemory), - 589: resources_core.FormatInt64(data.ResourceCPU), - 590: resources_core.FormatInt64(data.ResourceDisk), - 595: resources_core.FormatString(data.ResourceRealm), - 646: resources_core.FormatString(data.IpSpaceNameMaster), - 889: resources_core.FormatString(data.MasterAccessList), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 92, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 92, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "masterAccessList", Field: "MasterAccessList", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 92, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "masterAccessList", Field: "MasterAccessList", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *MongodbResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MongodbModel - var state MongodbModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if !strings.EqualFold(plan.IpSpaceNameMaster.ValueString(), state.IpSpaceNameMaster.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.MasterAccessList.IsNull() != state.MasterAccessList.IsNull() || plan.MasterAccessList.IsUnknown() != state.MasterAccessList.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.MasterAccessList.IsNull() && !plan.MasterAccessList.IsUnknown() && !state.MasterAccessList.IsNull() && !state.MasterAccessList.IsUnknown() { - if !strings.EqualFold(plan.MasterAccessList.ValueString(), state.MasterAccessList.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 648: resources_core.FormatInt64(plan.ResourceInstances), - 649: resources_core.FormatInt64(plan.ResourceMemory), - 650: resources_core.FormatInt64(plan.ResourceCPU), - 651: resources_core.FormatInt64(plan.ResourceDisk), - 653: resources_core.FormatString(plan.IpSpaceNameMaster), - 890: resources_core.FormatString(plan.MasterAccessList), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 92, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "masterAccessList", Field: "MasterAccessList", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MongodbModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *MongodbResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *MongodbResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/92_mongodb_user_resource.go b/generated/test/go/92_mongodb_user_resource.go deleted file mode 100644 index af2d6d9..0000000 --- a/generated/test/go/92_mongodb_user_resource.go +++ /dev/null @@ -1,368 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: mongodb -// Subresource: user - -var _ resource.Resource = &MongodbUserResource{} - -// MongodbUserResource manages a subresource via operations. -type MongodbUserResource struct { - client *core.UniversalClient -} - -type MongodbUserModel struct { - ID types.String `tfsdk:"id"` - MongodbID types.String `tfsdk:"mongodb_id"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - SkipMissingOnDelete types.Bool `tfsdk:"skip_missing_on_delete"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - DbName types.String `tfsdk:"db_name"` - Role types.String `tfsdk:"role"` - Username types.String `tfsdk:"username"` -} - -func NewMongodbUserResource() resource.Resource { - return &MongodbUserResource{} -} - -func (r *MongodbUserResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_mongodb_user" -} - -func (r *MongodbUserResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "mongodb_id": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, - }, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "skip_missing_on_delete": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "db_name": schema.StringAttribute{Required: true}, - "role": schema.StringAttribute{Required: true}, - "username": schema.StringAttribute{Required: true, MarkdownDescription: "Изменение требует пересоздания.", PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}}, - } - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *MongodbUserResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan MongodbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if plan.DbName.IsNull() || plan.DbName.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "db_name is required.") - return - } - if plan.Role.IsNull() || plan.Role.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "role is required.") - return - } - if plan.Username.IsNull() || plan.Username.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "username is required.") - return - } - - instanceUID := strings.TrimSpace(plan.MongodbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - adoptExistingOnCreate := !plan.AdoptExistingOnCreate.IsNull() && !plan.AdoptExistingOnCreate.IsUnknown() && plan.AdoptExistingOnCreate.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - if adoptExistingOnCreate { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Объект уже есть, выполняется усыновление: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - resp.Diagnostics.AddError("Подресурс уже существует", "Найден объект с таким именем: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "dbName": resources_core.FormatString(plan.DbName), - "role": resources_core.FormatString(plan.Role), - }) - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - createErr := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - if createErr != nil && resources_core.IsSubresourceTransientDependencyError(createErr) { - createErr = resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "create_user", params, operationTimeout) - } - if createErr != nil { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс подтверждён в state_out", "Операция create вернула ошибку, но объект найден в state_out и принят в state: "+targetValue) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - if adoptExistingOnCreate && resources_core.IsSubresourceAlreadyExistsError(createErr) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.AddWarning("Подресурс уже существует", "Операция вернула duplicate/exist, объект подтверждён в state_out, выполняется усыновление") - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - } - resp.Diagnostics.AddError("Нарушена консистентность", "Операция вернула duplicate/exist, но объект не найден в state_out") - return - } - resp.Diagnostics.AddError("Ошибка клиента", createErr.Error()) - return - } - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция create завершилась успешно, но объект не найден в state_out: "+targetValue) - return - } - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MongodbUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *MongodbUserResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan MongodbUserModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - - if "modify_user" == "" { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if plan.ID.IsNull() || plan.ID.IsUnknown() { - plan.ID = state.ID - } - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - instanceUID := strings.TrimSpace(plan.MongodbID.ValueString()) - if instanceUID == "" { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра") - return - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(plan.Username), - "dbName": resources_core.FormatString(plan.DbName), - "role": resources_core.FormatString(plan.Role), - }) - - idParams := map[string]string{ - "username": resources_core.FormatString(plan.Username), - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "modify_user", params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = types.StringValue(resources_core.BuildSubresourceID(instanceUID, "user", idParams)) - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) -} - -func (r *MongodbUserResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state MongodbUserModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - if "delete_user" == "" { - return - } - - instanceUID := strings.TrimSpace(state.MongodbID.ValueString()) - if instanceUID == "" { - return - } - skipMissingOnDelete := !state.SkipMissingOnDelete.IsNull() && !state.SkipMissingOnDelete.IsUnknown() && state.SkipMissingOnDelete.ValueBool() - - idParams := map[string]string{ - "username": resources_core.FormatString(state.Username), - } - identityCodes := []string{ - "username", - } - listKey, idKey := resources_core.ResolveSubresourceStateKeys("user", identityCodes) - targetValue := strings.TrimSpace(idParams[idKey]) - if targetValue == "" { - for _, code := range identityCodes { - candidate := strings.TrimSpace(idParams[code]) - if candidate == "" { - continue - } - targetValue = candidate - idKey = code - break - } - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && !found { - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Объект отсутствует и будет пропущен: "+targetValue) - return - } - resp.Diagnostics.AddError("Подресурс не найден", "Объект отсутствует: "+targetValue) - return - } - } - - params := resources_core.CompactParams(map[string]string{ - "username": resources_core.FormatString(state.Username), - }) - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.RunOperationByCodeWithTimeout(ctx, r.client, instanceUID, "delete_user", params, operationTimeout); err != nil { - if resources_core.IsSubresourceMissingError(err) { - if targetValue != "" { - found, known, checkErr := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if checkErr != nil { - resp.Diagnostics.AddError("Ошибка клиента", checkErr.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete вернула not found, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } - if skipMissingOnDelete { - resp.Diagnostics.AddWarning("Подресурс не найден", "Операция delete вернула not found, объект отсутствует в state_out, удаление пропущено") - return - } - } - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - if targetValue != "" { - found, known, err := resources_core.FindSubresourceInStateOut(ctx, r.client, instanceUID, listKey, idKey, targetValue) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if known && found { - resp.Diagnostics.AddError("Нарушена консистентность", "Операция delete завершилась успешно, но объект всё ещё присутствует в state_out: "+targetValue) - return - } - } -} - -func (r *MongodbUserResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/93_rabbitmq_resource.go b/generated/test/go/93_rabbitmq_resource.go deleted file mode 100644 index 7c90da2..0000000 --- a/generated/test/go/93_rabbitmq_resource.go +++ /dev/null @@ -1,457 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: rabbitmq -// Service ID: 93 - -var _ resource.Resource = &RabbitmqResource{} -var _ resource.ResourceWithModifyPlan = &RabbitmqResource{} -var _ resource.ResourceWithImportState = &RabbitmqResource{} - -type RabbitmqResource struct { - client *core.UniversalClient -} - -type RabbitmqModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - IpSpaceNameMaster types.String `tfsdk:"ip_space_name_master"` - NeedExternalAddressMaster types.Bool `tfsdk:"need_external_address_master"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewRabbitmqResource() resource.Resource { - return &RabbitmqResource{} -} - -func (r *RabbitmqResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_rabbitmq" -} - -func (r *RabbitmqResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "ip_space_name_master": schema.StringAttribute{Optional: true, MarkdownDescription: "Пример: `internet-no-antiddos-v1`"}, - "need_external_address_master": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false), MarkdownDescription: "Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`"}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1000), MarkdownDescription: "Пример: `2000`"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(30), MarkdownDescription: "Пример: `20`"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Пример: `1`"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1124), MarkdownDescription: "Пример: `2048`"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Выбрать платформу из списка Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *RabbitmqResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *RabbitmqModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 116: resources_core.FormatInt64(config.ResourceCPU), - 117: resources_core.FormatInt64(config.ResourceMemory), - 118: resources_core.FormatInt64(config.ResourceDisk), - 119: resources_core.FormatString(config.ResourceRealm), - 224: resources_core.FormatInt64(config.ResourceInstances), - 225: resources_core.FormatBool(config.NeedExternalAddressMaster), - 543: resources_core.FormatString(config.IpSpaceNameMaster), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 93, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *RabbitmqResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 93, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 116: resources_core.FormatInt64(data.ResourceCPU), - 117: resources_core.FormatInt64(data.ResourceMemory), - 118: resources_core.FormatInt64(data.ResourceDisk), - 119: resources_core.FormatString(data.ResourceRealm), - 224: resources_core.FormatInt64(data.ResourceInstances), - 225: resources_core.FormatBool(data.NeedExternalAddressMaster), - 543: resources_core.FormatString(data.IpSpaceNameMaster), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 93, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 93, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RabbitmqResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 93, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *RabbitmqResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan RabbitmqModel - var state RabbitmqModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.NeedExternalAddressMaster.IsNull() != state.NeedExternalAddressMaster.IsNull() || plan.NeedExternalAddressMaster.IsUnknown() != state.NeedExternalAddressMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.NeedExternalAddressMaster.IsNull() && !plan.NeedExternalAddressMaster.IsUnknown() && !state.NeedExternalAddressMaster.IsNull() && !state.NeedExternalAddressMaster.IsUnknown() { - if plan.NeedExternalAddressMaster.ValueBool() != state.NeedExternalAddressMaster.ValueBool() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IpSpaceNameMaster.IsNull() != state.IpSpaceNameMaster.IsNull() || plan.IpSpaceNameMaster.IsUnknown() != state.IpSpaceNameMaster.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IpSpaceNameMaster.IsNull() && !plan.IpSpaceNameMaster.IsUnknown() && !state.IpSpaceNameMaster.IsNull() && !state.IpSpaceNameMaster.IsUnknown() { - if !strings.EqualFold(plan.IpSpaceNameMaster.ValueString(), state.IpSpaceNameMaster.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 304: resources_core.FormatInt64(plan.ResourceCPU), - 305: resources_core.FormatInt64(plan.ResourceMemory), - 306: resources_core.FormatInt64(plan.ResourceDisk), - 307: resources_core.FormatInt64(plan.ResourceInstances), - 308: resources_core.FormatBool(plan.NeedExternalAddressMaster), - 545: resources_core.FormatString(plan.IpSpaceNameMaster), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 93, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "ipSpaceNameMaster", Field: "IpSpaceNameMaster", Type: "string"}, - {Code: "needExternalAddressMaster", Field: "NeedExternalAddressMaster", Type: "bool"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *RabbitmqResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state RabbitmqModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *RabbitmqResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *RabbitmqResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/94_lucee_resource.go b/generated/test/go/94_lucee_resource.go deleted file mode 100644 index eaa6524..0000000 --- a/generated/test/go/94_lucee_resource.go +++ /dev/null @@ -1,482 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: lucee -// Service ID: 94 - -var _ resource.Resource = &LuceeResource{} -var _ resource.ResourceWithModifyPlan = &LuceeResource{} -var _ resource.ResourceWithImportState = &LuceeResource{} - -type LuceeResource struct { - client *core.UniversalClient -} - -type LuceeModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - // --- Redeploy support (ARCHITECTURE.md) --- - // git_revision: при изменении вызывает redeploy вместо modify. - // Опциональное поле — если не задано, modify работает как обычно. - GitRevision types.String `tfsdk:"git_revision"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - AppConfiguration types.String `tfsdk:"app_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - JsonEnv types.String `tfsdk:"json_env"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewLuceeResource() resource.Resource { - return &LuceeResource{} -} - -func (r *LuceeResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_lucee" -} - -func (r *LuceeResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "app_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{}"), MarkdownDescription: "Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ"}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - // --- Redeploy support (ARCHITECTURE.md) --- - // При изменении git_revision вызывается redeploy вместо modify. - // Если не задано — modify работает без изменений. - "git_revision": schema.StringAttribute{Optional: true, MarkdownDescription: "Git revision (commit hash/tag). Changing this triggers redeploy instead of modify."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *LuceeResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *LuceeModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить access_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.AppConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "app_configuration is required.") - return - } - if config.AppConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 1019: resources_core.FormatString(config.StartupConfiguration), - 1020: resources_core.FormatString(config.ClusterConfiguration), - 1021: resources_core.FormatString(config.AccessConfiguration), - 1022: resources_core.FormatString(config.AppConfiguration), - 1023: resources_core.FormatString(config.JsonEnv), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 94, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *LuceeResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.AppConfiguration.IsNull() || data.AppConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "app_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 94, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 1019: resources_core.FormatString(data.StartupConfiguration), - 1020: resources_core.FormatString(data.ClusterConfiguration), - 1021: resources_core.FormatString(data.AccessConfiguration), - 1022: resources_core.FormatString(data.AppConfiguration), - 1023: resources_core.FormatString(data.JsonEnv), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 94, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 94, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 94, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *LuceeResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan LuceeModel - var state LuceeModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppConfiguration.IsNull() != state.AppConfiguration.IsNull() || plan.AppConfiguration.IsUnknown() != state.AppConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppConfiguration.IsNull() && !plan.AppConfiguration.IsUnknown() && !state.AppConfiguration.IsNull() && !state.AppConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AppConfiguration.ValueString(), state.AppConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if !strings.EqualFold(plan.JsonEnv.ValueString(), state.JsonEnv.ValueString()) { - hasServiceParamChanges = true - } - } - } - // --- Redeploy support (ARCHITECTURE.md) --- - // Проверяем изменился ли git_revision. - // Если да — вызываем redeploy вместо modify. - // git_revision = "" (не задано) → обычный modify. - redeployRequested := false - if !plan.GitRevision.IsNull() && !plan.GitRevision.IsUnknown() { - if state.GitRevision.IsNull() || state.GitRevision.IsUnknown() || plan.GitRevision.ValueString() != state.GitRevision.ValueString() { - redeployRequested = true - } - } - - if !hasServiceParamChanges && !redeployRequested { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - // --- Redeploy support (ARCHITECTURE.md) --- - if redeployRequested { - // Вызываем redeploy — пустой params (операция не требует CFS-параметров) - if err := r.client.RunRedeployOperation(ctx, instanceID.ValueString(), operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } else { - params := map[int]string{ - 1024: resources_core.FormatString(plan.ClusterConfiguration), - 1025: resources_core.FormatString(plan.AppConfiguration), - 1026: resources_core.FormatString(plan.JsonEnv), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 94, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *LuceeResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state LuceeModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *LuceeResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *LuceeResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/95_nodejs_resource.go b/generated/test/go/95_nodejs_resource.go deleted file mode 100644 index 9555693..0000000 --- a/generated/test/go/95_nodejs_resource.go +++ /dev/null @@ -1,482 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nodejs -// Service ID: 95 - -var _ resource.Resource = &NodejsResource{} -var _ resource.ResourceWithModifyPlan = &NodejsResource{} -var _ resource.ResourceWithImportState = &NodejsResource{} - -type NodejsResource struct { - client *core.UniversalClient -} - -type NodejsModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - // --- Redeploy support (ARCHITECTURE.md) --- - // git_revision: при изменении вызывает redeploy вместо modify. - // Опциональное поле — если не задано, modify работает как обычно. - GitRevision types.String `tfsdk:"git_revision"` - AccessConfiguration types.String `tfsdk:"access_configuration"` - AppConfiguration types.String `tfsdk:"app_configuration"` - ClusterConfiguration types.String `tfsdk:"cluster_configuration"` - JsonEnv types.String `tfsdk:"json_env"` - StartupConfiguration types.String `tfsdk:"startup_configuration"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNodejsResource() resource.Resource { - return &NodejsResource{} -} - -func (r *NodejsResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nodejs" -} - -func (r *NodejsResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "access_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - "app_configuration": schema.StringAttribute{Required: true}, - "cluster_configuration": schema.StringAttribute{Required: true}, - "json_env": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{}"), MarkdownDescription: "Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ"}, - "startup_configuration": schema.StringAttribute{Required: true, MarkdownDescription: "Не изменяется после создания."}, - // --- Redeploy support (ARCHITECTURE.md) --- - // При изменении git_revision вызывается redeploy вместо modify. - // Если не задано — modify работает без изменений. - "git_revision": schema.StringAttribute{Optional: true, MarkdownDescription: "Git revision (commit hash/tag). Changing this triggers redeploy instead of modify."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NodejsResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NodejsModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.AccessConfiguration.IsNull() && !plan.AccessConfiguration.IsUnknown() && !state.AccessConfiguration.IsNull() && !state.AccessConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.AccessConfiguration.ValueString(), state.AccessConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить access_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.StartupConfiguration.IsNull() && !plan.StartupConfiguration.IsUnknown() && !state.StartupConfiguration.IsNull() && !state.StartupConfiguration.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.StartupConfiguration.ValueString(), state.StartupConfiguration.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить startup_configuration", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.AccessConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if config.AccessConfiguration.IsUnknown() { - return - } - if config.AppConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "app_configuration is required.") - return - } - if config.AppConfiguration.IsUnknown() { - return - } - if config.ClusterConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if config.ClusterConfiguration.IsUnknown() { - return - } - if config.StartupConfiguration.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - if config.StartupConfiguration.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 1028: resources_core.FormatString(config.StartupConfiguration), - 1029: resources_core.FormatString(config.ClusterConfiguration), - 1030: resources_core.FormatString(config.AccessConfiguration), - 1031: resources_core.FormatString(config.AppConfiguration), - 1032: resources_core.FormatString(config.JsonEnv), - } - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 95, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NodejsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.AccessConfiguration.IsNull() || data.AccessConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "access_configuration is required.") - return - } - if data.AppConfiguration.IsNull() || data.AppConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "app_configuration is required.") - return - } - if data.ClusterConfiguration.IsNull() || data.ClusterConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "cluster_configuration is required.") - return - } - if data.StartupConfiguration.IsNull() || data.StartupConfiguration.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "startup_configuration is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 95, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 1028: resources_core.FormatString(data.StartupConfiguration), - 1029: resources_core.FormatString(data.ClusterConfiguration), - 1030: resources_core.FormatString(data.AccessConfiguration), - 1031: resources_core.FormatString(data.AppConfiguration), - 1032: resources_core.FormatString(data.JsonEnv), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 95, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 95, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NodejsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 95, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NodejsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NodejsModel - var state NodejsModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ClusterConfiguration.IsNull() != state.ClusterConfiguration.IsNull() || plan.ClusterConfiguration.IsUnknown() != state.ClusterConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ClusterConfiguration.IsNull() && !plan.ClusterConfiguration.IsUnknown() && !state.ClusterConfiguration.IsNull() && !state.ClusterConfiguration.IsUnknown() { - if !strings.EqualFold(plan.ClusterConfiguration.ValueString(), state.ClusterConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.AppConfiguration.IsNull() != state.AppConfiguration.IsNull() || plan.AppConfiguration.IsUnknown() != state.AppConfiguration.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.AppConfiguration.IsNull() && !plan.AppConfiguration.IsUnknown() && !state.AppConfiguration.IsNull() && !state.AppConfiguration.IsUnknown() { - if !strings.EqualFold(plan.AppConfiguration.ValueString(), state.AppConfiguration.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.JsonEnv.IsNull() != state.JsonEnv.IsNull() || plan.JsonEnv.IsUnknown() != state.JsonEnv.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - if !strings.EqualFold(plan.JsonEnv.ValueString(), state.JsonEnv.ValueString()) { - hasServiceParamChanges = true - } - } - } - // --- Redeploy support (ARCHITECTURE.md) --- - // Проверяем изменился ли git_revision. - // Если да — вызываем redeploy вместо modify. - // git_revision = "" (не задано) → обычный modify. - redeployRequested := false - if !plan.GitRevision.IsNull() && !plan.GitRevision.IsUnknown() { - if state.GitRevision.IsNull() || state.GitRevision.IsUnknown() || plan.GitRevision.ValueString() != state.GitRevision.ValueString() { - redeployRequested = true - } - } - - if !hasServiceParamChanges && !redeployRequested { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - // --- Redeploy support (ARCHITECTURE.md) --- - if redeployRequested { - // Вызываем redeploy — пустой params (операция не требует CFS-параметров) - if err := r.client.RunRedeployOperation(ctx, instanceID.ValueString(), operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } else { - params := map[int]string{ - 1033: resources_core.FormatString(plan.ClusterConfiguration), - 1034: resources_core.FormatString(plan.AppConfiguration), - 1035: resources_core.FormatString(plan.JsonEnv), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 95, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "accessConfiguration", Field: "AccessConfiguration", Type: "string"}, - {Code: "appConfiguration", Field: "AppConfiguration", Type: "string"}, - {Code: "clusterConfiguration", Field: "ClusterConfiguration", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "startupConfiguration", Field: "StartupConfiguration", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NodejsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NodejsModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NodejsResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NodejsResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/96_pgadmin_resource.go b/generated/test/go/96_pgadmin_resource.go deleted file mode 100644 index bc4b1b0..0000000 --- a/generated/test/go/96_pgadmin_resource.go +++ /dev/null @@ -1,510 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: pgadmin -// Service ID: 96 - -var _ resource.Resource = &PgadminResource{} -var _ resource.ResourceWithModifyPlan = &PgadminResource{} -var _ resource.ResourceWithImportState = &PgadminResource{} - -type PgadminResource struct { - client *core.UniversalClient -} - -type PgadminModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - // --- Redeploy support (ARCHITECTURE.md) --- - // git_revision: при изменении вызывает redeploy вместо modify. - // Опциональное поле — если не задано, modify работает как обычно. - GitRevision types.String `tfsdk:"git_revision"` - Domain types.String `tfsdk:"domain"` - Login types.String `tfsdk:"login"` - Password types.String `tfsdk:"password"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewPgadminResource() resource.Resource { - return &PgadminResource{} -} - -func (r *PgadminResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_pgadmin" -} - -func (r *PgadminResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "login": schema.StringAttribute{Required: true, MarkdownDescription: "Логин для подключения к pgAdmin, в формате email (login@email.net) Не изменяется после создания."}, - "password": schema.StringAttribute{Required: true, MarkdownDescription: "Пароль для подключения к pgAdmin Не изменяется после создания.", Sensitive: true}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (milicores). 1000Mili = 1 Ядро"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (MBytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - // --- Redeploy support (ARCHITECTURE.md) --- - // При изменении git_revision вызывается redeploy вместо modify. - // Если не задано — modify работает без изменений. - "git_revision": schema.StringAttribute{Optional: true, MarkdownDescription: "Git revision (commit hash/tag). Changing this triggers redeploy instead of modify."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *PgadminResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *PgadminModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Login.IsNull() && !plan.Login.IsUnknown() && !state.Login.IsNull() && !state.Login.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Login.ValueString(), state.Login.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить login", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.Password.IsNull() && !plan.Password.IsUnknown() && !state.Password.IsNull() && !state.Password.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Password.ValueString(), state.Password.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить password", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Login.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "login is required.") - return - } - if config.Login.IsUnknown() { - return - } - if config.Password.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "password is required.") - return - } - if config.Password.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 164: resources_core.FormatString(config.Domain), - 165: resources_core.FormatInt64(config.ResourceCPU), - 166: resources_core.FormatInt64(config.ResourceMemory), - 167: resources_core.FormatInt64(config.ResourceDisk), - 169: resources_core.FormatString(config.ResourceRealm), - 170: resources_core.FormatString(config.Login), - 171: resources_core.FormatString(config.Password), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 96, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *PgadminResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Login.IsNull() || data.Login.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "login is required.") - return - } - if data.Password.IsNull() || data.Password.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "password is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 96, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 164: resources_core.FormatString(data.Domain), - 165: resources_core.FormatInt64(data.ResourceCPU), - 166: resources_core.FormatInt64(data.ResourceMemory), - 167: resources_core.FormatInt64(data.ResourceDisk), - 169: resources_core.FormatString(data.ResourceRealm), - 170: resources_core.FormatString(data.Login), - 171: resources_core.FormatString(data.Password), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 96, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 96, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PgadminResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 96, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *PgadminResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan PgadminModel - var state PgadminModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - // --- Redeploy support (ARCHITECTURE.md) --- - // Проверяем изменился ли git_revision. - // Если да — вызываем redeploy вместо modify. - // git_revision = "" (не задано) → обычный modify. - redeployRequested := false - if !plan.GitRevision.IsNull() && !plan.GitRevision.IsUnknown() { - if state.GitRevision.IsNull() || state.GitRevision.IsUnknown() || plan.GitRevision.ValueString() != state.GitRevision.ValueString() { - redeployRequested = true - } - } - - if !hasServiceParamChanges && !redeployRequested { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - // --- Redeploy support (ARCHITECTURE.md) --- - if redeployRequested { - // Вызываем redeploy — пустой params (операция не требует CFS-параметров) - if err := r.client.RunRedeployOperation(ctx, instanceID.ValueString(), operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } else { - params := map[int]string{ - 172: resources_core.FormatInt64(plan.ResourceCPU), - 173: resources_core.FormatInt64(plan.ResourceMemory), - 174: resources_core.FormatInt64(plan.ResourceDisk), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 96, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "login", Field: "Login", Type: "string"}, - {Code: "password", Field: "Password", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *PgadminResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state PgadminModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *PgadminResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *PgadminResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/97_nodered_resource.go b/generated/test/go/97_nodered_resource.go deleted file mode 100644 index 2a1a8cb..0000000 --- a/generated/test/go/97_nodered_resource.go +++ /dev/null @@ -1,436 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: nodered -// Service ID: 97 - -var _ resource.Resource = &NoderedResource{} -var _ resource.ResourceWithModifyPlan = &NoderedResource{} -var _ resource.ResourceWithImportState = &NoderedResource{} - -type NoderedResource struct { - client *core.UniversalClient -} - -type NoderedModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewNoderedResource() resource.Resource { - return &NoderedResource{} -} - -func (r *NoderedResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_nodered" -} - -func (r *NoderedResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Required: true, MarkdownDescription: "Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро Не изменяется после создания."}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes) Не изменяется после создания."}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов Не изменяется после создания."}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes) Не изменяется после создания."}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *NoderedResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *NoderedModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_c_p_u", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_disk", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_instances", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - resp.Diagnostics.AddError("Нельзя изменить resource_memory", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.Domain.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if config.Domain.IsUnknown() { - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 193: resources_core.FormatInt64(config.ResourceCPU), - 194: resources_core.FormatInt64(config.ResourceMemory), - 195: resources_core.FormatInt64(config.ResourceDisk), - 196: resources_core.FormatString(config.ResourceRealm), - 197: resources_core.FormatString(config.Domain), - 323: resources_core.FormatInt64(config.ResourceInstances), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 97, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *NoderedResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.Domain.IsNull() || data.Domain.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "domain is required.") - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 97, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 193: resources_core.FormatInt64(data.ResourceCPU), - 194: resources_core.FormatInt64(data.ResourceMemory), - 195: resources_core.FormatInt64(data.ResourceDisk), - 196: resources_core.FormatString(data.ResourceRealm), - 197: resources_core.FormatString(data.Domain), - 323: resources_core.FormatInt64(data.ResourceInstances), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 97, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 97, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NoderedResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 97, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *NoderedResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan NoderedModel - var state NoderedModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{} - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 97, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *NoderedResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state NoderedModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "delete" - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *NoderedResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *NoderedResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/98_http_resource.go b/generated/test/go/98_http_resource.go deleted file mode 100644 index f21348a..0000000 --- a/generated/test/go/98_http_resource.go +++ /dev/null @@ -1,504 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: http -// Service ID: 98 - -var _ resource.Resource = &HttpResource{} -var _ resource.ResourceWithModifyPlan = &HttpResource{} -var _ resource.ResourceWithImportState = &HttpResource{} - -type HttpResource struct { - client *core.UniversalClient -} - -type HttpModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - // --- Redeploy support (ARCHITECTURE.md) --- - // git_revision: при изменении вызывает redeploy вместо modify. - // Опциональное поле — если не задано, modify работает как обычно. - GitRevision types.String `tfsdk:"git_revision"` - Domain types.String `tfsdk:"domain"` - IngressAnnotations types.String `tfsdk:"ingress_annotations"` - JsonEnv types.String `tfsdk:"json_env"` - RegistryPath types.String `tfsdk:"registry_path"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - ResourceRealm types.String `tfsdk:"resource_realm"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewHttpResource() resource.Resource { - return &HttpResource{} -} - -func (r *HttpResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_http" -} - -func (r *HttpResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "ingress_annotations": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("{}"), MarkdownDescription: "Формат ключ/значение
Поддерживает пока простые аннотации Не изменяется после создания."}, - "json_env": schema.StringAttribute{Optional: true, MarkdownDescription: "Массив переменных, будут переданы в env приложения Не изменяется после создания."}, - "registry_path": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("nexus-sa.tst.nubes.ru/docker-nubes/jolt"), MarkdownDescription: "Путь до image, который будет установлен как deployment Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(100), MarkdownDescription: "Квота ядра пода (Указывается в mili)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(200), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "resource_realm": schema.StringAttribute{Required: true, MarkdownDescription: "Платформа для развертывания Не изменяется после создания."}, - // --- Redeploy support (ARCHITECTURE.md) --- - // При изменении git_revision вызывается redeploy вместо modify. - // Если не задано — modify работает без изменений. - "git_revision": schema.StringAttribute{Optional: true, MarkdownDescription: "Git revision (commit hash/tag). Changing this triggers redeploy instead of modify."}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *HttpResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *HttpModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.IngressAnnotations.IsNull() && !plan.IngressAnnotations.IsUnknown() && !state.IngressAnnotations.IsNull() && !state.IngressAnnotations.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.IngressAnnotations.ValueString(), state.IngressAnnotations.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить ingress_annotations", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.JsonEnv.IsNull() && !plan.JsonEnv.IsUnknown() && !state.JsonEnv.IsNull() && !state.JsonEnv.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.JsonEnv.ValueString(), state.JsonEnv.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить json_env", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.RegistryPath.IsNull() && !plan.RegistryPath.IsUnknown() && !state.RegistryPath.IsNull() && !state.RegistryPath.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.RegistryPath.ValueString(), state.RegistryPath.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить registry_path", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.ResourceRealm.IsNull() && !plan.ResourceRealm.IsUnknown() && !state.ResourceRealm.IsNull() && !state.ResourceRealm.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.ResourceRealm.ValueString(), state.ResourceRealm.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить resource_realm", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.ResourceRealm.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - if config.ResourceRealm.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - params := map[int]string{ - 212: resources_core.FormatString(config.Domain), - 213: resources_core.FormatInt64(config.ResourceCPU), - 214: resources_core.FormatInt64(config.ResourceMemory), - 215: resources_core.FormatInt64(config.ResourceInstances), - 216: resources_core.FormatString(config.ResourceRealm), - 217: resources_core.FormatString(config.RegistryPath), - 241: resources_core.FormatString(config.JsonEnv), - 782: resources_core.FormatString(config.IngressAnnotations), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 98, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *HttpResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.ResourceRealm.IsNull() || data.ResourceRealm.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "resource_realm is required.") - return - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 98, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 212: resources_core.FormatString(data.Domain), - 213: resources_core.FormatInt64(data.ResourceCPU), - 214: resources_core.FormatInt64(data.ResourceMemory), - 215: resources_core.FormatInt64(data.ResourceInstances), - 216: resources_core.FormatString(data.ResourceRealm), - 217: resources_core.FormatString(data.RegistryPath), - 241: resources_core.FormatString(data.JsonEnv), - 782: resources_core.FormatString(data.IngressAnnotations), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 98, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 98, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "ingressAnnotations", Field: "IngressAnnotations", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HttpResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 98, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "ingressAnnotations", Field: "IngressAnnotations", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *HttpResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan HttpModel - var state HttpModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - // --- Redeploy support (ARCHITECTURE.md) --- - // Проверяем изменился ли git_revision. - // Если да — вызываем redeploy вместо modify. - // git_revision = "" (не задано) → обычный modify. - redeployRequested := false - if !plan.GitRevision.IsNull() && !plan.GitRevision.IsUnknown() { - if state.GitRevision.IsNull() || state.GitRevision.IsUnknown() || plan.GitRevision.ValueString() != state.GitRevision.ValueString() { - redeployRequested = true - } - } - - if !hasServiceParamChanges && !redeployRequested { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - // --- Redeploy support (ARCHITECTURE.md) --- - if redeployRequested { - // Вызываем redeploy — пустой params (операция не требует CFS-параметров) - if err := r.client.RunRedeployOperation(ctx, instanceID.ValueString(), operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } else { - params := map[int]string{ - 218: resources_core.FormatInt64(plan.ResourceCPU), - 219: resources_core.FormatInt64(plan.ResourceMemory), - 220: resources_core.FormatInt64(plan.ResourceInstances), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 98, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "ingressAnnotations", Field: "IngressAnnotations", Type: "string"}, - {Code: "jsonEnv", Field: "JsonEnv", Type: "string"}, - {Code: "registryPath", Field: "RegistryPath", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - {Code: "resourceRealm", Field: "ResourceRealm", Type: "string"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *HttpResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state HttpModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *HttpResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *HttpResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/99_gitea_resource.go b/generated/test/go/99_gitea_resource.go deleted file mode 100644 index 954de53..0000000 --- a/generated/test/go/99_gitea_resource.go +++ /dev/null @@ -1,574 +0,0 @@ -package resources_gen - -import ( - "context" - "strings" - - "terraform-provider-nubes/internal/core" - "terraform-provider-nubes/internal/resources_core" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" -) - -// Code generated by tools/gen_v2. DO NOT EDIT. -// Service: gitea -// Service ID: 99 - -var _ resource.Resource = &GiteaResource{} -var _ resource.ResourceWithModifyPlan = &GiteaResource{} -var _ resource.ResourceWithImportState = &GiteaResource{} - -type GiteaResource struct { - client *core.UniversalClient -} - -type GiteaModel struct { - ID types.String `tfsdk:"id"` - ResourceName types.String `tfsdk:"resource_name"` - OperationTimeout types.String `tfsdk:"operation_timeout"` - LogLevel types.String `tfsdk:"log_level"` - Domain types.String `tfsdk:"domain"` - IngressExtraAnnotations types.String `tfsdk:"ingress_extra_annotations"` - IniServerParams types.String `tfsdk:"ini_server_params"` - PsqlUid types.String `tfsdk:"psql_uid"` - ResourceCPU types.Int64 `tfsdk:"resource_c_p_u"` - ResourceDisk types.Int64 `tfsdk:"resource_disk"` - ResourceInstances types.Int64 `tfsdk:"resource_instances"` - ResourceMemory types.Int64 `tfsdk:"resource_memory"` - SuspendOnDestroy types.Bool `tfsdk:"suspend_on_destroy"` - AdoptExistingOnCreate types.Bool `tfsdk:"adopt_existing_on_create"` - StateParams types.Map `tfsdk:"state_params"` - StateOut types.Map `tfsdk:"state_out"` - StateParamsFlat types.Map `tfsdk:"state_params_flat"` - StateOutFlat types.Map `tfsdk:"state_out_flat"` - VaultSecrets types.Map `tfsdk:"vault_secrets"` - VaultUrl types.String `tfsdk:"vault_url"` - VaultUserPath types.String `tfsdk:"vault_user_path"` - VaultFields types.List `tfsdk:"vault_fields"` -} - -func NewGiteaResource() resource.Resource { - return &GiteaResource{} -} - -func (r *GiteaResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_gitea" -} - -func (r *GiteaResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - attrs := map[string]schema.Attribute{ - "id": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, - "resource_name": schema.StringAttribute{Required: true}, - "operation_timeout": schema.StringAttribute{Optional: true}, - "log_level": schema.StringAttribute{Optional: true, MarkdownDescription: "Operation stages log level: none (default), info, debug. Overrides provider-level log_level."}, - "domain": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("web01"), MarkdownDescription: "Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm Не изменяется после создания."}, - "ingress_extra_annotations": schema.StringAttribute{Optional: true}, - "ini_server_params": schema.StringAttribute{Optional: true}, - "psql_uid": schema.StringAttribute{Optional: true, Computed: true, MarkdownDescription: "UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически Не изменяется после создания."}, - "resource_c_p_u": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500), MarkdownDescription: "Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро"}, - "resource_disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Квота диска (Указывается в GIGAbytes)"}, - "resource_instances": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1), MarkdownDescription: "Количество узлов"}, - "resource_memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512), MarkdownDescription: "Квота памяти пода (Указывается в Megabytes)"}, - "suspend_on_destroy": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(true)}, - "adopt_existing_on_create": schema.BoolAttribute{Optional: true, Computed: true, Default: booldefault.StaticBool(false)}, - "state_params": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_params_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "state_out_flat": schema.MapAttribute{Computed: true, ElementType: types.StringType}, - "vault_secrets": schema.MapAttribute{Computed: true, ElementType: types.StringType, Sensitive: true}, - "vault_url": schema.StringAttribute{Computed: true}, - "vault_user_path": schema.StringAttribute{Computed: true}, - "vault_fields": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - } - - resp.Schema = schema.Schema{Attributes: attrs} -} - -func (r *GiteaResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - if r.client == nil { - return - } - - var config *GiteaModel - resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) - if resp.Diagnostics.HasError() { - return - } - if config == nil { - return - } - - var state *GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if req.State.Raw.IsNull() && req.Plan.Raw.IsNull() { - return - } - - if state != nil && !state.ID.IsNull() && !state.ID.IsUnknown() { - var plan GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - if resp.Diagnostics.HasError() { - return - } - // FIX(uuid-case): resolve ref_svc params НЕ делаем в ModifyPlan. - // Terraform правило: plan ОБЯЗАН равняться config для user-provided атрибутов. - // Resolve (displayName → UUID или uppercase → lowercase) нужен только для - // API-вызова в Create/Update. Делать его здесь = менять plan = ошибка - // "Provider produced invalid plan: planned value does not match config value". - if !plan.ResourceName.IsNull() && !plan.ResourceName.IsUnknown() && !state.ResourceName.IsNull() && !state.ResourceName.IsUnknown() { - if plan.ResourceName.ValueString() != state.ResourceName.ValueString() { - resp.Diagnostics.AddError("Нельзя изменить resource_name", "Параметр resource_name задается при создании и не может быть изменен. Создайте новый ресурс с другим именем.") - return - } - } - if !plan.Domain.IsNull() && !plan.Domain.IsUnknown() && !state.Domain.IsNull() && !state.Domain.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.Domain.ValueString(), state.Domain.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить domain", "Параметр задается при создании и не может быть изменен.") - return - } - } - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - // FIX(uuid-case): сравниваем без учёта регистра — API возвращает UUID - // в lowercase, пользователь мог написать upper/mixed. Это одно и то же - // значение, менять его нельзя только если оно реально другое. - if !strings.EqualFold(plan.PsqlUid.ValueString(), state.PsqlUid.ValueString()) { - resp.Diagnostics.AddError("Нельзя изменить psql_uid", "Параметр задается при создании и не может быть изменен.") - return - } - } - return - } - if config.PsqlUid.IsNull() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - if config.PsqlUid.IsUnknown() { - return - } - - if config.ResourceName.IsNull() || config.ResourceName.IsUnknown() { - return - } - adoptExistingOnCreate := false - if !config.AdoptExistingOnCreate.IsNull() && !config.AdoptExistingOnCreate.IsUnknown() { - adoptExistingOnCreate = config.AdoptExistingOnCreate.ValueBool() - } - if !config.PsqlUid.IsNull() && !config.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, config.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != config.PsqlUid.ValueString() { - config.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - params := map[int]string{ - 232: resources_core.FormatInt64(config.ResourceCPU), - 233: resources_core.FormatInt64(config.ResourceMemory), - 234: resources_core.FormatInt64(config.ResourceDisk), - 235: resources_core.FormatInt64(config.ResourceInstances), - 237: resources_core.FormatString(config.Domain), - 238: resources_core.FormatString(config.PsqlUid), - 818: resources_core.FormatString(config.IngressExtraAnnotations), - 821: resources_core.FormatString(config.IniServerParams), - } - desiredDomain := "" - if !config.Domain.IsNull() && !config.Domain.IsUnknown() { - desiredDomain = config.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - - resp.Diagnostics.Append(resources_core.PlanExistingResourceDiagnosticsWithParamsAndDomainAndServices(ctx, r.client, 99, config.ResourceName.ValueString(), adoptExistingOnCreate, params, desiredDomain, domainServiceIDs)...) -} - -func (r *GiteaResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - if data.PsqlUid.IsNull() || data.PsqlUid.IsUnknown() { - resp.Diagnostics.AddError("Missing required attribute", "psql_uid is required.") - return - } - // ══════════════════════════════════════════════════════════════════════════ - // ПРАВИЛО TERRAFORM (официальная документация): - // «If an attribute value is configured, it is NEVER valid to change that - // value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что - // написал пользователь). Менять plan запрещено на уровне фреймворка. - // - // ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре. - // Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный). - // После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит: - // «Provider produced inconsistent result after apply». - // - // РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот. - // Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как - // ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API). - // Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный - // регистр в state через strings.EqualFold (сравниваем без учёта регистра). - // ══════════════════════════════════════════════════════════════════════════ - originalPsqlUid := data.PsqlUid - if !data.PsqlUid.IsNull() && !data.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, data.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if resolvedPsqlUid != "" && resolvedPsqlUid != data.PsqlUid.ValueString() { - data.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - - resourceName := data.ResourceName.ValueString() - desiredDomain := "" - if !data.Domain.IsNull() && !data.Domain.IsUnknown() { - desiredDomain = data.Domain.ValueString() - } - domainServiceIDs := []int{81, 82, 88, 96, 97, 98, 99, 119, 149} - resp.Diagnostics.Append(resources_core.CreateExistingResourceDiagnosticsWithDomainAndServices(ctx, r.client, 99, resourceName, data.AdoptExistingOnCreate.ValueBool(), desiredDomain, domainServiceIDs)...) - - params := map[int]string{ - 232: resources_core.FormatInt64(data.ResourceCPU), - 233: resources_core.FormatInt64(data.ResourceMemory), - 234: resources_core.FormatInt64(data.ResourceDisk), - 235: resources_core.FormatInt64(data.ResourceInstances), - 237: resources_core.FormatString(data.Domain), - 238: resources_core.FormatString(data.PsqlUid), - 818: resources_core.FormatString(data.IngressExtraAnnotations), - 821: resources_core.FormatString(data.IniServerParams), - } - - operationTimeout := "" - if !data.OperationTimeout.IsNull() && !data.OperationTimeout.IsUnknown() { - operationTimeout = data.OperationTimeout.ValueString() - } - if !data.LogLevel.IsNull() && !data.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, data.LogLevel.ValueString()) - } - id, err := resources_core.CreateResourceWithTimeout(ctx, r.client, 99, resourceName, data.AdoptExistingOnCreate.ValueBool(), params, operationTimeout) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - data.ID = types.StringValue(id) - - state, diags := resources_core.RefreshResourceState(ctx, r.client, id, 99, data, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "ingressExtraAnnotations", Field: "IngressExtraAnnotations", Type: "string"}, - {Code: "iniServerParams", Field: "IniServerParams", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - // Restore user-provided casing в state (Create). - // EqualFold = «совпадают ли значения без учёта регистра?» - // Если да — значит API вернул «туже» строку, только в другом регистре. - // Заменяем state на original (то что было в plan/config пользователя). - // Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint. - if !originalPsqlUid.IsNull() && !originalPsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - if strings.EqualFold(state.PsqlUid.ValueString(), originalPsqlUid.ValueString()) { - state.PsqlUid = originalPsqlUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - if r.client != nil { - remove, err := resources_core.ShouldRemoveFromState(ctx, r.client, state.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - if remove { - resp.State.RemoveResource(ctx) - return - } - } - - newState, diags := resources_core.RefreshResourceState(ctx, r.client, state.ID.ValueString(), 99, state, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "ingressExtraAnnotations", Field: "IngressExtraAnnotations", Type: "string"}, - {Code: "iniServerParams", Field: "IniServerParams", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !newState.PsqlUid.IsNull() && !newState.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, newState.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != newState.PsqlUid.ValueString() { - newState.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - // Restore user-provided casing в state (Read). - // При чтении у нас нет plan — но предыдущий state уже хранит значение - // в регистре пользователя (после первого Create оно было восстановлено). - // Берём prior state (переменная state) как эталон регистра. - // Если API вернул то же UUID только строчными буквами — восстанавливаем. - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() && !newState.PsqlUid.IsNull() && !newState.PsqlUid.IsUnknown() { - if strings.EqualFold(newState.PsqlUid.ValueString(), state.PsqlUid.ValueString()) { - newState.PsqlUid = state.PsqlUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...) -} - -func (r *GiteaResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan GiteaModel - var state GiteaModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - instanceID := state.ID - if instanceID.IsNull() || instanceID.IsUnknown() { - instanceID = plan.ID - } - if instanceID.IsNull() || instanceID.IsUnknown() { - resp.Diagnostics.AddError("Ошибка клиента", "отсутствует идентификатор экземпляра для modify") - return - } - - hasServiceParamChanges := false - if !hasServiceParamChanges { - if plan.ResourceCPU.IsNull() != state.ResourceCPU.IsNull() || plan.ResourceCPU.IsUnknown() != state.ResourceCPU.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceCPU.IsNull() && !plan.ResourceCPU.IsUnknown() && !state.ResourceCPU.IsNull() && !state.ResourceCPU.IsUnknown() { - if plan.ResourceCPU.ValueInt64() != state.ResourceCPU.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceMemory.IsNull() != state.ResourceMemory.IsNull() || plan.ResourceMemory.IsUnknown() != state.ResourceMemory.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceMemory.IsNull() && !plan.ResourceMemory.IsUnknown() && !state.ResourceMemory.IsNull() && !state.ResourceMemory.IsUnknown() { - if plan.ResourceMemory.ValueInt64() != state.ResourceMemory.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceDisk.IsNull() != state.ResourceDisk.IsNull() || plan.ResourceDisk.IsUnknown() != state.ResourceDisk.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceDisk.IsNull() && !plan.ResourceDisk.IsUnknown() && !state.ResourceDisk.IsNull() && !state.ResourceDisk.IsUnknown() { - if plan.ResourceDisk.ValueInt64() != state.ResourceDisk.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.ResourceInstances.IsNull() != state.ResourceInstances.IsNull() || plan.ResourceInstances.IsUnknown() != state.ResourceInstances.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.ResourceInstances.IsNull() && !plan.ResourceInstances.IsUnknown() && !state.ResourceInstances.IsNull() && !state.ResourceInstances.IsUnknown() { - if plan.ResourceInstances.ValueInt64() != state.ResourceInstances.ValueInt64() { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IngressExtraAnnotations.IsNull() != state.IngressExtraAnnotations.IsNull() || plan.IngressExtraAnnotations.IsUnknown() != state.IngressExtraAnnotations.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IngressExtraAnnotations.IsNull() && !plan.IngressExtraAnnotations.IsUnknown() && !state.IngressExtraAnnotations.IsNull() && !state.IngressExtraAnnotations.IsUnknown() { - if !strings.EqualFold(plan.IngressExtraAnnotations.ValueString(), state.IngressExtraAnnotations.ValueString()) { - hasServiceParamChanges = true - } - } - } - if !hasServiceParamChanges { - if plan.IniServerParams.IsNull() != state.IniServerParams.IsNull() || plan.IniServerParams.IsUnknown() != state.IniServerParams.IsUnknown() { - hasServiceParamChanges = true - } else if !plan.IniServerParams.IsNull() && !plan.IniServerParams.IsUnknown() && !state.IniServerParams.IsNull() && !state.IniServerParams.IsUnknown() { - if !strings.EqualFold(plan.IniServerParams.ValueString(), state.IniServerParams.ValueString()) { - hasServiceParamChanges = true - } - } - } - - if !hasServiceParamChanges { - plan.ID = instanceID - plan.StateParams = state.StateParams - plan.StateOut = state.StateOut - plan.StateParamsFlat = state.StateParamsFlat - plan.StateOutFlat = state.StateOutFlat - plan.VaultSecrets = state.VaultSecrets - plan.VaultUrl = state.VaultUrl - plan.VaultUserPath = state.VaultUserPath - plan.VaultFields = state.VaultFields - resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) - return - } - - operationTimeout := "" - if !plan.OperationTimeout.IsNull() && !plan.OperationTimeout.IsUnknown() { - operationTimeout = plan.OperationTimeout.ValueString() - } - if !plan.LogLevel.IsNull() && !plan.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, plan.LogLevel.ValueString()) - } - params := map[int]string{ - 259: resources_core.FormatInt64(plan.ResourceCPU), - 260: resources_core.FormatInt64(plan.ResourceMemory), - 261: resources_core.FormatInt64(plan.ResourceDisk), - 262: resources_core.FormatInt64(plan.ResourceInstances), - 819: resources_core.FormatString(plan.IngressExtraAnnotations), - 820: resources_core.FormatString(plan.IniServerParams), - } - if err := resources_core.UpdateResourceWithTimeout(ctx, r.client, instanceID.ValueString(), params, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } - - plan.ID = instanceID - state, diags := resources_core.RefreshResourceState(ctx, r.client, instanceID.ValueString(), 99, plan, []resources_core.StateField{ - {Code: "state_params"}, - {Code: "state_out"}, - {Code: "state_params_flat"}, - {Code: "state_out_flat"}, - {Code: "vault_secrets"}, - {Code: "vault_url"}, - {Code: "vault_user_path"}, - {Code: "vault_fields"}, - }, []resources_core.InputField{ - {Code: "domain", Field: "Domain", Type: "string"}, - {Code: "ingressExtraAnnotations", Field: "IngressExtraAnnotations", Type: "string"}, - {Code: "iniServerParams", Field: "IniServerParams", Type: "string"}, - {Code: "psqlUid", Field: "PsqlUid", Type: "string"}, - {Code: "resourceCPU", Field: "ResourceCPU", Type: "int64"}, - {Code: "resourceDisk", Field: "ResourceDisk", Type: "int64"}, - {Code: "resourceInstances", Field: "ResourceInstances", Type: "int64"}, - {Code: "resourceMemory", Field: "ResourceMemory", Type: "int64"}, - }) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - if !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - resolvedPsqlUid, err := r.client.ResolveRefSvcParamValue(ctx, 90, state.PsqlUid.ValueString()) - if err != nil { - resp.Diagnostics.AddWarning("Failed to resolve psql_uid", err.Error()) - } else if resolvedPsqlUid != "" && resolvedPsqlUid != state.PsqlUid.ValueString() { - state.PsqlUid = types.StringValue(resolvedPsqlUid) - } - } - // Restore user-provided casing в state (Update). - // После API-вызова modify state содержит значения в lower-case от API. - // Plan == config == то что написал пользователь (регистр неизменён). - // EqualFold: если UUID совпадает без учёта регистра — берём из plan. - if !plan.PsqlUid.IsNull() && !plan.PsqlUid.IsUnknown() && !state.PsqlUid.IsNull() && !state.PsqlUid.IsUnknown() { - if strings.EqualFold(state.PsqlUid.ValueString(), plan.PsqlUid.ValueString()) { - state.PsqlUid = plan.PsqlUid - } - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) -} - -func (r *GiteaResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state GiteaModel - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - if state.ID.IsNull() || state.ID.IsUnknown() { - return - } - deleteMode := "state_only" - if !state.SuspendOnDestroy.IsNull() && !state.SuspendOnDestroy.IsUnknown() && state.SuspendOnDestroy.ValueBool() { - deleteMode = "suspend" - } - - operationTimeout := "" - if !state.OperationTimeout.IsNull() && !state.OperationTimeout.IsUnknown() { - operationTimeout = state.OperationTimeout.ValueString() - } - if !state.LogLevel.IsNull() && !state.LogLevel.IsUnknown() { - ctx = core.CtxWithLogLevel(ctx, state.LogLevel.ValueString()) - } - if err := resources_core.DeleteResourceWithTimeout(ctx, r.client, state.ID.ValueString(), deleteMode, operationTimeout); err != nil { - resp.Diagnostics.AddError("Ошибка клиента", err.Error()) - return - } -} - -func (r *GiteaResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func (r *GiteaResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - client, ok := req.ProviderData.(*core.UniversalClient) - if !ok { - resp.Diagnostics.AddError("Error", "Invalid client type") - return - } - r.client = client -} diff --git a/generated/test/go/registry.go b/generated/test/go/registry.go deleted file mode 100644 index 58a4539..0000000 --- a/generated/test/go/registry.go +++ /dev/null @@ -1,67 +0,0 @@ -package resources_gen - -import "github.com/hashicorp/terraform-plugin-framework/resource" - -// Code generated by tools/gen_v2. DO NOT EDIT. -func AllResources() []func() resource.Resource { - return []func() resource.Resource{ - NewAkhqResource, - NewClickhouseResource, - NewDnsrecordResource, - NewDnszoneResource, - NewDummyResource, - NewFlaskResource, - NewGiteaResource, - NewGiteaComplexResource, - NewHarborResource, - NewHttpResource, - NewK8sSthutrvalClusterResource, - NewK8sZitiControllerResource, - NewKafkaResource, - NewLuceeResource, - NewMariadbResource, - NewMongodbResource, - NewNextcloudResource, - NewNifiResource, - NewNodejsResource, - NewNoderedResource, - NewOpenwhiskResource, - NewPgadminResource, - NewPostgresResource, - NewRabbitmqResource, - NewRedisResource, - NewS3Resource, - NewS3bucketResource, - NewSupersetResource, - NewTemplateResource, - NewTenantResource, - NewValoTenantResource, - NewVappResource, - NewVcComplexResource, - NewVcNsxtResource, - NewVcOrgResource, - NewVcOrgSaasResource, - NewVcVdcResource, - NewVcVdcGroupResource, - NewVcVmResource, - NewVcVmV2Resource, - NewVcVmV3Resource, - NewVcexternalipResource, - NewVmpostgreResource, - NewClickhouseDatabaseResource, - NewClickhouseUserResource, - NewK8sSthutrvalClusterUserResource, - NewKafkaTopicResource, - NewKafkaUserResource, - NewMariadbDatabaseResource, - NewMariadbUserResource, - NewMongodbUserResource, - NewNextcloudBackupResource, - NewPostgresBackupResource, - NewPostgresDatabaseResource, - NewPostgresUserResource, - NewS3SubUserResource, - NewVcOrgUserResource, - NewVcVdcGroupVdcResource, - } -} diff --git a/generated/test/json/.gitkeep b/generated/test/json/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/test/output_inventory/index.json b/generated/test/output_inventory/index.json deleted file mode 100644 index a5c66ca..0000000 --- a/generated/test/output_inventory/index.json +++ /dev/null @@ -1,496 +0,0 @@ -[ - { - "serviceId": 110, - "svc_code": "DNS зона", - "instance_count": 2, - "state_params_keys": [], - "state_out_keys": [], - "vault_keys": [] - }, - { - "serviceId": 111, - "svc_code": "DNS запись", - "instance_count": 5, - "state_params_keys": [ - "recordInput", - "recordName", - "recordTTL", - "recordType", - "zoneUid" - ], - "state_out_keys": [ - "dnsServers", - "record" - ], - "vault_keys": [ - "fields", - "userPath" - ] - }, - { - "serviceId": 112, - "svc_code": "Тенант в Grafana", - "instance_count": 1, - "state_params_keys": [ - "resourceRealm" - ], - "state_out_keys": [ - "connectionUrl", - "monitoring" - ], - "vault_keys": [ - "fields", - "userPath" - ] - }, - { - "serviceId": 116, - "svc_code": "ApacheKafka", - "instance_count": 2, - "state_params_keys": [], - "state_out_keys": [], - "vault_keys": [] - }, - { - "serviceId": 12, - "svc_code": "S3 Object Storage", - "instance_count": 1, - "state_params_keys": [ - "maxBucketsPerUser", - "maxObjectsPerBucket", - "maxSizeGbPerUser", - "resourceRealm", - "userName" - ], - "state_out_keys": [ - "dtEndTrial", - "dtStartTrial", - "isTrial", - "monitoring", - "urlConnect" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 13, - "svc_code": "S3 бакет", - "instance_count": 6, - "state_params_keys": [ - "bucketName", - "corsAll", - "listAll", - "maxSize", - "placement", - "readAll", - "s3UserUid" - ], - "state_out_keys": [ - "httpConnect" - ], - "vault_keys": [] - }, - { - "serviceId": 150, - "svc_code": "Kubernetes кластер Штурвал", - "instance_count": 1, - "state_params_keys": [ - "access", - "accessConfiguration", - "clusterConfiguration", - "controlPlaneConfiguration", - "startupConfiguration", - "workerConfiguration" - ], - "state_out_keys": [ - "ingressAddress", - "kubernetesApiAddress", - "webUrl" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 19, - "svc_code": "Организация в Cloud Director", - "instance_count": 1, - "state_params_keys": [ - "organizationType", - "resourceRealm", - "vIPConfigure" - ], - "state_out_keys": [ - "urlConnect" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 1, - "svc_code": "Болванка", - "instance_count": 1, - "state_params_keys": [], - "state_out_keys": [], - "vault_keys": [] - }, - { - "serviceId": 21, - "svc_code": "Виртуальный датацентр (vDC)", - "instance_count": 1, - "state_params_keys": [ - "cpuAllocated", - "cpuGuaranteed", - "memAllocated", - "memGuaranteed", - "networkProvider", - "organizationUid", - "providerVdc", - "storageConfig" - ], - "state_out_keys": [ - "sizingPolicies", - "vdcName" - ], - "vault_keys": [] - }, - { - "serviceId": 22, - "svc_code": "Сетевой шлюз периметра (Edge)", - "instance_count": 1, - "state_params_keys": [ - "ipSpaceName", - "needEnableAVI", - "needExternalAddressSNAT", - "vdcGroupUid", - "vdcType", - "vdcUid", - "virtualServicesCount" - ], - "state_out_keys": [ - "nsxName", - "routedNet", - "vdcName" - ], - "vault_keys": [] - }, - { - "serviceId": 25, - "svc_code": "Публичные IP адреса", - "instance_count": 2, - "state_params_keys": [ - "dnatCreate", - "fromServiceCloudEdgeName", - "fromServiceCloudEdgeScope", - "fromServiceCloudOrgName", - "fromServiceCloudVdcName", - "fromServiceCloudVmwareUrl", - "fromServiceNamespace", - "fromServiceVdcGroupName", - "internalAddrAccess", - "internalPortAccess", - "ipSpaceName", - "resourceRealm", - "serviceUid", - "snatCreate" - ], - "state_out_keys": [ - "externalIp" - ], - "vault_keys": [ - "fields", - "userPath" - ] - }, - { - "serviceId": 26, - "svc_code": "Виртуальный каталог ВМ (vApp)", - "instance_count": 2, - "state_params_keys": [ - "nsxtUid", - "vappName", - "vdcUid" - ], - "state_out_keys": [], - "vault_keys": [] - }, - { - "serviceId": 28, - "svc_code": "Виртуальная машина", - "instance_count": 2, - "state_params_keys": [ - "accessIpList", - "accessPortList", - "cloudInit", - "imageVm", - "ipSpaceName", - "userLogin", - "userPublicKey", - "vappUid", - "vmCpu", - "vmDisk", - "vmName", - "vmRam" - ], - "state_out_keys": [ - "externalConnect", - "fqdn", - "internalConnect", - "monitoring" - ], - "vault_keys": [] - }, - { - "serviceId": 81, - "svc_code": "Apache Superset", - "instance_count": 2, - "state_params_keys": [], - "state_out_keys": [], - "vault_keys": [] - }, - { - "serviceId": 89, - "svc_code": "Web-сервер с фреймворком Flask", - "instance_count": 4, - "state_params_keys": [ - "domain", - "gitPath", - "healthPath", - "jsonEnv", - "resourceCPU", - "resourceInstances", - "resourceMemory", - "resourceRealm" - ], - "state_out_keys": [ - "connectionUrl", - "monitoring" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 90, - "svc_code": "PostgreSQL", - "instance_count": 3, - "state_params_keys": [ - "allowNoSSL", - "appVersion", - "autoScale", - "autoScalePercentage", - "autoScaleQuotaGb", - "autoScaleTechWindow", - "enablePgPoolerMaster", - "enablePgPoolerSlave", - "ext_BACKUP_NUM_TO_RETAIN", - "ext_BACKUP_SCHEDULE", - "ipSpaceNameMaster", - "ipSpaceNameSlave", - "jsonParameters", - "needExternalAddressMaster", - "needExternalAddressSlave", - "resourceCPU", - "resourceDisk", - "resourceInstances", - "resourceMemory", - "resourceRealm", - "s3Uid" - ], - "state_out_keys": [ - "databases", - "externalConnect", - "internalConnect", - "monitoring", - "users" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 91, - "svc_code": "Redis", - "instance_count": 3, - "state_params_keys": [ - "needExternalAddressMaster", - "needExternalAddressSlave", - "resourceCPU", - "resourceDisk", - "resourceInstances", - "resourceMemory", - "resourceRealm" - ], - "state_out_keys": [ - "externalConnect", - "internalConnect", - "monitoring" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 92, - "svc_code": "MongoDB", - "instance_count": 2, - "state_params_keys": [ - "needExternalAddressMaster", - "resourceCPU", - "resourceDisk", - "resourceInstances", - "resourceMemory", - "resourceRealm" - ], - "state_out_keys": [ - "internalConnect", - "monitoring" - ], - "vault_keys": [] - }, - { - "serviceId": 93, - "svc_code": "RabbitMQ", - "instance_count": 1, - "state_params_keys": [ - "needExternalAddressMaster", - "resourceCPU", - "resourceDisk", - "resourceInstances", - "resourceMemory", - "resourceRealm" - ], - "state_out_keys": [ - "clusterDomain", - "externalConnect", - "inernalConnect", - "monitoring" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 94, - "svc_code": "Lucee", - "instance_count": 1, - "state_params_keys": [ - "appVersion", - "domain", - "gitPath", - "healthPath", - "jsonEnv", - "resourceCPU", - "resourceInstances", - "resourceMemory", - "resourceRealm" - ], - "state_out_keys": [ - "connectionUrl", - "monitoring" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 95, - "svc_code": "NodeJS", - "instance_count": 1, - "state_params_keys": [ - "appVersion", - "domain", - "gitPath", - "healthPath", - "jsonEnv", - "resourceCPU", - "resourceInstances", - "resourceMemory", - "resourceRealm" - ], - "state_out_keys": [ - "connectionUrl", - "monitoring" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 96, - "svc_code": "pgAdmin", - "instance_count": 3, - "state_params_keys": [ - "domain", - "login", - "password", - "resourceCPU", - "resourceDisk", - "resourceInstances", - "resourceMemory", - "resourceRealm" - ], - "state_out_keys": [ - "connectionUrl", - "monitoring" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - }, - { - "serviceId": 97, - "svc_code": "NodeRed", - "instance_count": 4, - "state_params_keys": [ - "resourceRealm" - ], - "state_out_keys": [], - "vault_keys": [] - }, - { - "serviceId": 98, - "svc_code": "Простой HTTP контейнер", - "instance_count": 2, - "state_params_keys": [ - "domain", - "jsonEnv", - "registryPath", - "resourceCPU", - "resourceInstances", - "resourceMemory", - "resourceRealm" - ], - "state_out_keys": [ - "connectionUrl", - "monitoring" - ], - "vault_keys": [ - "fields", - "url", - "userPath" - ] - } -] \ No newline at end of file diff --git a/generated/test/output_inventory/svc_110_DNS_зона.json b/generated/test/output_inventory/svc_110_DNS_зона.json deleted file mode 100644 index 4888ed9..0000000 --- a/generated/test/output_inventory/svc_110_DNS_зона.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "serviceId": 110, - "svc_code": "DNS зона", - "instances": [ - { - "uid": "CF5863D1-1BE7-46DA-992C-904A3A76979E", - "name": "inv-svc-110-r4", - "serviceId": 110, - "svc_code": "DNS зона", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "3F5695A1-6CFA-4213-867B-EA9170566D35", - "name": "inv-svc-110-r5", - "serviceId": 110, - "svc_code": "DNS зона", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "094053f9-0acb-49c8-89da-e09e7a06f832", - "name": "supermax", - "serviceId": 110, - "svc_code": "DNS зона", - "status": "running", - "source": "prod", - "params": { - "zoneTtl": "86400", - "zoneKind": "NATIVE", - "zoneName": "k8c.ru", - "zoneEmail": "tazet@narod.ru", - "zoneRetry": "7200", - "zoneExpire": "3600000", - "zoneRefresh": "86400", - "resourceRealm": "powerdns", - "zoneMastersForSlave": "" - }, - "out": { - "dnsServers": [ - "185.247.187.83", - "81.22.46.43" - ], - "zoneSerial": "2025102601", - "zoneSoaServer": "ns.ngcloud.ru" - }, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_111_DNS_запись.json b/generated/test/output_inventory/svc_111_DNS_запись.json deleted file mode 100644 index db469f2..0000000 --- a/generated/test/output_inventory/svc_111_DNS_запись.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "serviceId": 111, - "svc_code": "DNS запись", - "instances": [ - { - "uid": "cbd153bd-5d17-42f3-acc2-d0cfdf75c036", - "name": "A-record (web-test-stand.luceek8s)", - "status": "running", - "params": { - "zoneUid": "4398ca1b-e96d-4829-90b7-d7eb0e798389", - "recordTTL": "300", - "recordName": "web-test-stand.luceek8s", - "recordType": "A", - "recordInput": "91.214.116.222" - }, - "out": { - "record": "web-test-stand.luceek8s.dev.nubes.ru", - "dnsServers": [ - "185.247.187.83", - "81.22.46.43" - ] - }, - "vault_keys": [ - "fields", - "userPath" - ] - }, - { - "uid": "97b4ab52-74b9-4146-955f-d855b878b376", - "name": "A-record (web02.vapp-sless.a9f8779d-4b8f-40be-bcaf-9427fab6ce4b)", - "status": "running", - "params": { - "zoneUid": "4398ca1b-e96d-4829-90b7-d7eb0e798389", - "recordTTL": "300", - "recordName": "web02.vapp-sless.a9f8779d-4b8f-40be-bcaf-9427fab6ce4b", - "recordType": "A", - "recordInput": "185.247.187.154" - }, - "out": { - "record": "web02.vapp-sless.a9f8779d-4b8f-40be-bcaf-9427fab6ce4b.dev.nubes.ru", - "dnsServers": [ - "185.247.187.83", - "81.22.46.43" - ] - }, - "vault_keys": [ - "fields", - "userPath" - ] - }, - { - "uid": "d4d7c97f-efa8-4885-b919-8c037c20524a", - "name": "A-record (node07.nodejsk8s)", - "status": "running", - "params": { - "zoneUid": "4398ca1b-e96d-4829-90b7-d7eb0e798389", - "recordTTL": "300", - "recordName": "node07.nodejsk8s", - "recordType": "A", - "recordInput": "91.214.116.222" - }, - "out": { - "record": "node07.nodejsk8s.dev.nubes.ru", - "dnsServers": [ - "185.247.187.83", - "81.22.46.43" - ] - }, - "vault_keys": [ - "fields", - "userPath" - ] - }, - { - "uid": "ad471cd8-1b2e-4747-af41-b4b730ed846e", - "name": "A-record (baogg.openbaok8s)", - "status": "running", - "params": { - "zoneUid": "4398ca1b-e96d-4829-90b7-d7eb0e798389", - "recordTTL": "300", - "recordName": "baogg.openbaok8s", - "recordType": "A", - "recordInput": "91.214.116.222" - }, - "out": { - "record": "baogg.openbaok8s.dev.nubes.ru", - "dnsServers": [ - "185.247.187.83", - "81.22.46.43" - ] - }, - "vault_keys": [ - "fields", - "userPath" - ] - }, - { - "uid": "9fa09e8c-2725-4efa-ace6-83123ed5ebfc", - "name": "A-record (admin.1dbfe9da-ce1c-4958-b359-d016a4b455c8)", - "status": "running", - "params": { - "zoneUid": "4398ca1b-e96d-4829-90b7-d7eb0e798389", - "recordTTL": "300", - "recordName": "admin.1dbfe9da-ce1c-4958-b359-d016a4b455c8", - "recordType": "A", - "recordInput": "185.247.187.147" - }, - "out": { - "record": "admin.1dbfe9da-ce1c-4958-b359-d016a4b455c8.dev.nubes.ru", - "dnsServers": [ - "185.247.187.83", - "81.22.46.43" - ] - }, - "vault_keys": [ - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_112_Тенант_в_Grafana.json b/generated/test/output_inventory/svc_112_Тенант_в_Grafana.json deleted file mode 100644 index cf661fc..0000000 --- a/generated/test/output_inventory/svc_112_Тенант_в_Grafana.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "serviceId": 112, - "svc_code": "Тенант в Grafana", - "instances": [ - { - "uid": "19696eb9-5af5-4e0a-ad00-f49a10d755d4", - "name": "Grafana Tenant (WZ03709)", - "status": "running", - "params": { - "resourceRealm": "grafana.ngcloud.ru" - }, - "out": { - "monitoring": { - "pdu": { - "url": "https://grafana.ngcloud.ru/d/19696eb9-5af5-4e0a-ad00-f49a10d755d4-pd3?orgId=962" - }, - "vms": { - "url": "https://grafana.ngcloud.ru/d/19696eb9-5af5-4e0a-ad00-f49a10d755d4-vm2?orgId=962" - }, - "resourceMetrics": "https://grafana.ngcloud.ru/dashboards/f/19696eb9-5af5-4e0a-ad00-f49a10d755d4?orgId=962" - }, - "connectionUrl": "https://grafana.ngcloud.ru/?orgId=962" - }, - "vault_keys": [ - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_116_ApacheKafka.json b/generated/test/output_inventory/svc_116_ApacheKafka.json deleted file mode 100644 index 97a16d5..0000000 --- a/generated/test/output_inventory/svc_116_ApacheKafka.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "serviceId": 116, - "svc_code": "ApacheKafka", - "instances": [ - { - "uid": "71763169-2053-420E-8CFF-69410E41C978", - "name": "inv-svc-116-1774957184", - "serviceId": 116, - "svc_code": "ApacheKafka", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "DA96A991-E8B7-43C0-8C97-9947A6A0C333", - "name": "inv-svc-116-r2", - "serviceId": 116, - "svc_code": "ApacheKafka", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "bd1d689e-bce2-4792-9f1f-73cd1d6c7de7", - "name": "tf-kafka-20260203-01", - "serviceId": 116, - "svc_code": "ApacheKafka", - "status": "running", - "source": "prod", - "params": { - "resourceCPU": 1000, - "resourceDisk": "1", - "resourceRealm": "k8s-3.ext.nubes.ru", - "resourceMemory": 1000, - "ipSpaceNameMaster": "", - "resourceInstances": 1, - "needExternalAddressMaster": "false" - }, - "out": { - "monitoring": { - "base": { - "url": "https://grafana.ngcloud.ru/d/bd1d689e-bce2-4792-9f1f-73cd1d6c7de7-def?orgId=28" - }, - "loki": { - "url": "https://grafana.ngcloud.ru/d/bd1d689e-bce2-4792-9f1f-73cd1d6c7de7-log?orgId=28" - }, - "allDashboards": "https://grafana.ngcloud.ru/dashboards/f/bd1d689e-bce2-4792-9f1f-73cd1d6c7de7?orgId=28" - }, - "externalConnect": { - "bootstrap": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - } - }, - "internalConnect": "kafkak8s-kafka-bootstrap.bd1d689e-bce2-4792-9f1f-73cd1d6c7de7.svc.k8s-3.ext.nubes.ru" - }, - "vault_keys": [] - }, - { - "uid": "18257650-5edd-40e9-bcd9-98c85add3a19", - "name": "kafka-2", - "serviceId": 116, - "svc_code": "ApacheKafka", - "status": "suspended", - "source": "prod", - "params": { - "resourceCPU": 2000, - "resourceDisk": "10", - "resourceRealm": "k8s-3.ext.nubes.ru", - "resourceMemory": 2048, - "ipSpaceNameMaster": "internet-no-antiddos-v1", - "resourceInstances": 2, - "needExternalAddressMaster": false - }, - "out": { - "kafkaUsers": { - "usertest": { - "group": "*", - "nameTopic": "*", - "operations": "Create, Describe, Read, Write", - "accessHosts": "*" - } - }, - "monitoring": { - "base": { - "url": "https://grafana.ngcloud.ru/d/18257650-5edd-40e9-bcd9-98c85add3a19-def?orgId=28" - }, - "loki": { - "url": "https://grafana.ngcloud.ru/d/18257650-5edd-40e9-bcd9-98c85add3a19-log?orgId=28" - }, - "allDashboards": "https://grafana.ngcloud.ru/dashboards/f/18257650-5edd-40e9-bcd9-98c85add3a19?orgId=28" - }, - "kafkaTopics": { - "test-events": { - "replicas": "2", - "partitions": "6" - } - }, - "externalConnect": { - "bootstrap": { - "ip": "", - "fqdn": "", - "uuid": "7defcbcc-543e-4967-b83d-8bdd3b4592ae", - "isExternal": false - } - }, - "internalConnect": "kafkak8s-kafka-bootstrap.18257650-5edd-40e9-bcd9-98c85add3a19.svc.k8s-3.ext.nubes.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_119_Akhq.json b/generated/test/output_inventory/svc_119_Akhq.json deleted file mode 100644 index ce1b49d..0000000 --- a/generated/test/output_inventory/svc_119_Akhq.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "serviceId": 119, - "svc_code": "Akhq", - "instances": [ - { - "uid": "305707e5-2e64-4bfa-ad41-3141e3449791", - "name": "Akhq-4", - "serviceId": 119, - "svc_code": "Akhq", - "status": "suspended", - "source": "prod", - "params": { - "domain": "", - "resourceCPU": "", - "resourceRealm": "", - "resourceMemory": "", - "resourceInstances": "" - }, - "out": { - "connectionUrl": "https://akhq2002.akhqk8s.services.ngcloud.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_12_S3_Object_Storage.json b/generated/test/output_inventory/svc_12_S3_Object_Storage.json deleted file mode 100644 index 88fa6ca..0000000 --- a/generated/test/output_inventory/svc_12_S3_Object_Storage.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "serviceId": 12, - "svc_code": "S3 Object Storage", - "instances": [ - { - "uid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "name": "naeel-s3", - "status": "running", - "params": { - "userName": "naeels3", - "resourceRealm": "ceph.tst.nubes.ru", - "maxSizeGbPerUser": "1024", - "maxBucketsPerUser": 25, - "maxObjectsPerBucket": "10000000" - }, - "out": { - "isTrial": true, - "dtEndTrial": "2026-03-27T18:16:11.026+0300", - "monitoring": { - "s3ceph": { - "url": "https://grafana.ngcloud.ru/d/332cdb0d-34bf-43bf-864d-4adcc3b556fb-s3?orgId=962" - }, - "resourceMetrics": "https://grafana.ngcloud.ru/dashboards/f/332cdb0d-34bf-43bf-864d-4adcc3b556fb?orgId=962" - }, - "urlConnect": "http://ceph.tst.nubes.ru", - "dtStartTrial": "2026-03-13T18:16:11.026+0300" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_13_S3_бакет.json b/generated/test/output_inventory/svc_13_S3_бакет.json deleted file mode 100644 index 09411a0..0000000 --- a/generated/test/output_inventory/svc_13_S3_бакет.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "serviceId": 13, - "svc_code": "S3 бакет", - "instances": [ - { - "uid": "37f35a6b-ec3e-404b-b8aa-16d43317fd79", - "name": "S3-Bucket (technicals3backup-f97978e3-9300-41bb-b22c-4f9aecf674f8)", - "status": "running", - "params": { - "corsAll": "false", - "listAll": "false", - "maxSize": "-1", - "readAll": "false", - "placement": "COLD", - "s3UserUid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "bucketName": "technicals3backup-f97978e3-9300-41bb-b22c-4f9aecf674f8" - }, - "out": { - "httpConnect": "http://ceph.tst.nubes.ru/technicals3backup-f97978e3-9300-41bb-b22c-4f9aecf674f8" - }, - "vault_keys": [] - }, - { - "uid": "bc401b9c-6b55-466c-b6e5-85131b69ecf9", - "name": "S3-Bucket (technicals3backup-f87f606f-b32e-4eb2-9563-8c3bf88a2d82)", - "status": "running", - "params": { - "corsAll": "false", - "listAll": "false", - "maxSize": "-1", - "readAll": "false", - "placement": "COLD", - "s3UserUid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "bucketName": "technicals3backup-f87f606f-b32e-4eb2-9563-8c3bf88a2d82" - }, - "out": { - "httpConnect": "http://ceph.tst.nubes.ru/technicals3backup-f87f606f-b32e-4eb2-9563-8c3bf88a2d82" - }, - "vault_keys": [] - }, - { - "uid": "99260e62-4e05-4f2f-ad4c-217d79ef8f1f", - "name": "S3-Bucket (technicals3backup-bba55e0f-4c51-4312-8ad3-efc557de331d)", - "status": "running", - "params": { - "corsAll": "false", - "listAll": "false", - "maxSize": "-1", - "readAll": "false", - "placement": "COLD", - "s3UserUid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "bucketName": "technicals3backup-bba55e0f-4c51-4312-8ad3-efc557de331d" - }, - "out": { - "httpConnect": "http://ceph.tst.nubes.ru/technicals3backup-bba55e0f-4c51-4312-8ad3-efc557de331d" - }, - "vault_keys": [] - }, - { - "uid": "c7b50a72-ef23-40c8-86c0-a6c07883444f", - "name": "S3-Bucket (technicals3backup-99dd3428-7a98-453c-a7a3-9930bc7af299)", - "status": "running", - "params": { - "corsAll": "false", - "listAll": "false", - "maxSize": "-1", - "readAll": "false", - "placement": "COLD", - "s3UserUid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "bucketName": "technicals3backup-99dd3428-7a98-453c-a7a3-9930bc7af299" - }, - "out": { - "httpConnect": "http://ceph.tst.nubes.ru/technicals3backup-99dd3428-7a98-453c-a7a3-9930bc7af299" - }, - "vault_keys": [] - }, - { - "uid": "c1a622ba-50a9-4344-ae5f-1b32c38cb344", - "name": "poc-s3evt-src", - "status": "running", - "params": { - "corsAll": "false", - "listAll": "false", - "maxSize": "-1", - "readAll": "false", - "placement": "HOT", - "s3UserUid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "bucketName": "poc-s3evt-src" - }, - "out": { - "httpConnect": "http://ceph.tst.nubes.ru/poc-s3evt-src" - }, - "vault_keys": [] - }, - { - "uid": "c1a622ba-50a9-4344-ae5f-1b32c38cb344", - "name": "poc-s3evt-src", - "status": "running", - "params": { - "corsAll": "false", - "listAll": "false", - "maxSize": "-1", - "readAll": "false", - "placement": "HOT", - "s3UserUid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "bucketName": "poc-s3evt-src" - }, - "out": { - "httpConnect": "http://ceph.tst.nubes.ru/poc-s3evt-src" - }, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_150_Kubernetes_кластер_Штурвал.json b/generated/test/output_inventory/svc_150_Kubernetes_кластер_Штурвал.json deleted file mode 100644 index cbf972b..0000000 --- a/generated/test/output_inventory/svc_150_Kubernetes_кластер_Штурвал.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "serviceId": 150, - "svc_code": "Kubernetes кластер Штурвал", - "instances": [ - { - "uid": "0fcbae6c-d4b5-4f53-8619-a59fcff1d0b5", - "name": "naeel-wheel", - "status": "running", - "params": { - "access": { - "accessIpListAPI": "[]", - "accessIpListIngress": "[]", - "needExternalAddressAPI": "true", - "needExternalAddressIngress": "true" - }, - "accessConfiguration": { - "accessIpListAPI": "[]", - "accessIpListIngress": "[]", - "needExternalAddressAPI": "true", - "needExternalAddressIngress": "true" - }, - "workerConfiguration": [ - { - "count": "3", - "groupName": "workers", - "sizingDisk": "50", - "sizingPolicy": "TKG 4CPU 8RAM" - } - ], - "clusterConfiguration": { - "appVersion": "2.12.1" - }, - "startupConfiguration": { - "vdcUid": "e3c9e4f1-24da-4992-a003-f8a2a803a5f0", - "nsxtUid": "0fe88e2a-31b6-4385-ad52-e27c6c0d38a6", - "clusterName": "naeel-test-3" - }, - "controlPlaneConfiguration": { - "count": "3", - "sizingDisk": "50", - "sizingPolicy": "TKG 4CPU 8RAM" - } - }, - "out": { - "webUrl": "https://k8s.ngcloud.ru/clusters/naeel-test-3/dashboard", - "ingressAddress": "185.247.187.147", - "kubernetesApiAddress": "185.247.187.146" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_19_Организация_в_Cloud_Director.json b/generated/test/output_inventory/svc_19_Организация_в_Cloud_Director.json deleted file mode 100644 index b2daf66..0000000 --- a/generated/test/output_inventory/svc_19_Организация_в_Cloud_Director.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "serviceId": 19, - "svc_code": "Организация в Cloud Director", - "instances": [ - { - "uid": "3f0850f2-3506-4efd-b84b-7270b5027ab5", - "name": "NaeelOrg", - "status": "running", - "params": { - "vIPConfigure": [ - { - "name": "internet-ipv4-v1", - "count": "10" - } - ], - "resourceRealm": "sandbox.nubes.ru", - "organizationType": "iaas" - }, - "out": { - "urlConnect": "https://sandbox.nubes.ru/tenant/WZ03709-iaas/" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_1_Болванка.json b/generated/test/output_inventory/svc_1_Болванка.json deleted file mode 100644 index f02d7d6..0000000 --- a/generated/test/output_inventory/svc_1_Болванка.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "serviceId": 1, - "svc_code": "Болванка", - "instances": [ - { - "uid": "94B28619-7FA8-4B51-AB2F-DC8E5CE4A02C", - "name": "inv-dummy-1774955714", - "serviceId": 1, - "svc_code": "Болванка", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_21_Виртуальный_датацентр_(vDC).json b/generated/test/output_inventory/svc_21_Виртуальный_датацентр_(vDC).json deleted file mode 100644 index eff792c..0000000 --- a/generated/test/output_inventory/svc_21_Виртуальный_датацентр_(vDC).json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "serviceId": 21, - "svc_code": "Виртуальный датацентр (vDC)", - "instances": [ - { - "uid": "e3c9e4f1-24da-4992-a003-f8a2a803a5f0", - "name": "naeel-vdc", - "status": "running", - "params": { - "providerVdc": "Intel Broadwell 2.4", - "cpuAllocated": "40", - "memAllocated": "100", - "cpuGuaranteed": "20", - "memGuaranteed": "20", - "storageConfig": [ - { - "name": "SSD", - "size": "2000" - } - ], - "networkProvider": "snb1", - "organizationUid": "3f0850f2-3506-4efd-b84b-7270b5027ab5" - }, - "out": { - "vdcName": "WZ03709-iaas-sandbox-v1cl1-pvdc-ywmmd", - "sizingPolicies": [ - "TKG 16CPU 32RAM", - "TKG 2CPU 4RAM", - "TKG 4CPU 8RAM", - "TKG 8CPU 16RAM" - ] - }, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_22_Сетевой_шлюз_периметра_(Edge).json b/generated/test/output_inventory/svc_22_Сетевой_шлюз_периметра_(Edge).json deleted file mode 100644 index aaf5574..0000000 --- a/generated/test/output_inventory/svc_22_Сетевой_шлюз_периметра_(Edge).json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "serviceId": 22, - "svc_code": "Сетевой шлюз периметра (Edge)", - "instances": [ - { - "uid": "0fe88e2a-31b6-4385-ad52-e27c6c0d38a6", - "name": "naeel_vc_nsxt", - "status": "running", - "params": { - "vdcUid": "e3c9e4f1-24da-4992-a003-f8a2a803a5f0", - "vdcType": "vdc", - "ipSpaceName": "internet-ipv4-v1", - "vdcGroupUid": "", - "needEnableAVI": true, - "virtualServicesCount": "4", - "needExternalAddressSNAT": true - }, - "out": { - "nsxName": "nsx_WZ03709-iaas-h67go75t", - "vdcName": "WZ03709-iaas-sandbox-v1cl1-pvdc-ywmmd", - "routedNet": "routed_WZ03709-iaas-htpse6fu" - }, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_25_Публичные_IP_адреса.json b/generated/test/output_inventory/svc_25_Публичные_IP_адреса.json deleted file mode 100644 index 9f0c93a..0000000 --- a/generated/test/output_inventory/svc_25_Публичные_IP_адреса.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "serviceId": 25, - "svc_code": "Публичные IP адреса", - "instances": [ - { - "uid": "1b613370-3aef-4034-9840-859af1223d85", - "name": "vIp for (a9f8779d-4b8f-40be-bcaf-9427fab6ce4b)", - "status": "running", - "params": { - "dnatCreate": "true", - "serviceUid": "a9f8779d-4b8f-40be-bcaf-9427fab6ce4b", - "snatCreate": "true", - "ipSpaceName": "internet-ipv4-v1", - "resourceRealm": "sandbox.nubes.ru", - "internalAddrAccess": "10.10.102.6", - "internalPortAccess": [ - "all" - ], - "fromServiceNamespace": "web02", - "fromServiceCloudOrgName": "WZ03709-iaas", - "fromServiceCloudVdcName": "WZ03709-iaas-sandbox-v1cl1-pvdc-ywmmd", - "fromServiceVdcGroupName": "", - "fromServiceCloudEdgeName": "nsx_WZ03709-iaas-h67go75t", - "fromServiceCloudEdgeScope": "vdc", - "fromServiceCloudVmwareUrl": "https://sandbox.nubes.ru" - }, - "out": { - "externalIp": "185.247.187.154" - }, - "vault_keys": [ - "fields", - "userPath" - ] - }, - { - "uid": "d9b02475-f23a-4316-8d75-4a684c58fed9", - "name": "vIp for (0fe88e2a-31b6-4385-ad52-e27c6c0d38a6)", - "status": "running", - "params": { - "dnatCreate": "false", - "serviceUid": "0fe88e2a-31b6-4385-ad52-e27c6c0d38a6", - "snatCreate": "true", - "ipSpaceName": "internet-ipv4-v1", - "resourceRealm": "sandbox.nubes.ru", - "internalAddrAccess": "10.10.102.0/24", - "internalPortAccess": [ - "all" - ], - "fromServiceNamespace": "master", - "fromServiceCloudOrgName": "WZ03709-iaas", - "fromServiceCloudVdcName": "WZ03709-iaas-sandbox-v1cl1-pvdc-ywmmd", - "fromServiceVdcGroupName": "", - "fromServiceCloudEdgeName": "nsx_WZ03709-iaas-h67go75t", - "fromServiceCloudEdgeScope": "vdc", - "fromServiceCloudVmwareUrl": "https://sandbox.nubes.ru" - }, - "out": { - "externalIp": "185.247.187.140" - }, - "vault_keys": [ - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_26_Виртуальный_каталог_ВМ_(vApp).json b/generated/test/output_inventory/svc_26_Виртуальный_каталог_ВМ_(vApp).json deleted file mode 100644 index 8fd6364..0000000 --- a/generated/test/output_inventory/svc_26_Виртуальный_каталог_ВМ_(vApp).json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "serviceId": 26, - "svc_code": "Виртуальный каталог ВМ (vApp)", - "instances": [ - { - "uid": "f037ddea-fc1d-46c5-9eef-577e07878c9c", - "name": "vm-sless-vapp", - "status": "suspended", - "params": { - "vdcUid": "e3c9e4f1-24da-4992-a003-f8a2a803a5f0", - "nsxtUid": "0fe88e2a-31b6-4385-ad52-e27c6c0d38a6", - "vappName": "vapp-sless" - }, - "out": {}, - "vault_keys": [] - }, - { - "uid": "6214ba32-79e1-435d-9a21-6e41e563daf5", - "name": "vm-sless-demo-vapp", - "status": "suspended", - "params": { - "vdcUid": "e3c9e4f1-24da-4992-a003-f8a2a803a5f0", - "nsxtUid": "0fe88e2a-31b6-4385-ad52-e27c6c0d38a6", - "vappName": "vapp-sless-demo" - }, - "out": {}, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_28_Виртуальная_машина.json b/generated/test/output_inventory/svc_28_Виртуальная_машина.json deleted file mode 100644 index fcc37c6..0000000 --- a/generated/test/output_inventory/svc_28_Виртуальная_машина.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "serviceId": 28, - "svc_code": "Виртуальная машина", - "instances": [ - { - "uid": "a9f8779d-4b8f-40be-bcaf-9427fab6ce4b", - "name": "vm-sless-1", - "status": "suspended", - "params": { - "vmCpu": "2", - "vmRam": "2", - "vmDisk": "20", - "vmName": "web02", - "imageVm": "Ubuntu_22-20G", - "vappUid": "f037ddea-fc1d-46c5-9eef-577e07878c9c", - "cloudInit": "", - "userLogin": "ubuntu", - "ipSpaceName": "internet-ipv4-v1", - "accessIpList": [], - "userPublicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKQB+Kyevn0H8QSdfm6ZpCU9jtskBxUS9BV0+i1/M04A sless-demo-vm", - "accessPortList": [ - "22" - ] - }, - "out": { - "fqdn": "web02.vapp-sless.a9f8779d-4b8f-40be-bcaf-9427fab6ce4b.dev.nubes.ru", - "monitoring": { - "allDashboards": "https://grafana.ngcloud.ru/d/b14bce94-2f96-4b7f-a424-a59f0df055ad/vm?orgId=954&var-VM_NAME=web02-tUuP-cloud" - }, - "externalConnect": "185.247.187.154", - "internalConnect": "10.10.102.6" - }, - "vault_keys": [] - }, - { - "uid": "212231af-e95a-4f80-b0f6-795d9b23d780", - "name": "vm-sless", - "status": "suspended", - "params": { - "vmCpu": "2", - "vmRam": "2", - "vmDisk": "20", - "vmName": "web01", - "imageVm": "Ubuntu_22-20G", - "vappUid": "fba91c08-3ca4-4c4f-8d0c-f92b75c9e67e", - "cloudInit": "", - "userLogin": "ubuntu", - "ipSpaceName": "internet-ipv4-v1", - "accessIpList": [], - "userPublicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKQB+Kyevn0H8QSdfm6ZpCU9jtskBxUS9BV0+i1/M04A sless-demo-vm", - "accessPortList": [ - "22" - ] - }, - "out": { - "fqdn": "web01.vapp-sless.212231af-e95a-4f80-b0f6-795d9b23d780.dev.nubes.ru", - "monitoring": { - "allDashboards": "https://grafana.ngcloud.ru/d/b14bce94-2f96-4b7f-a424-a59f0df055ad/vm?orgId=954&var-VM_NAME=web01-POhS-cloud" - }, - "externalConnect": "185.247.187.154", - "internalConnect": "10.10.102.6" - }, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_81_Apache_Superset.json b/generated/test/output_inventory/svc_81_Apache_Superset.json deleted file mode 100644 index 00d13d3..0000000 --- a/generated/test/output_inventory/svc_81_Apache_Superset.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "serviceId": 81, - "svc_code": "Apache Superset", - "instances": [ - { - "uid": "A6998702-90EA-4006-B19D-4EBBAD9EBBE8", - "name": "inv-svc-81-1774957205", - "serviceId": 81, - "svc_code": "Apache Superset", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "546FABC3-4113-4B10-8A60-F5CCAC36B34A", - "name": "inv-svc-81-r4", - "serviceId": 81, - "svc_code": "Apache Superset", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_82_Container Registry.json b/generated/test/output_inventory/svc_82_Container Registry.json deleted file mode 100644 index 2e02b6f..0000000 --- a/generated/test/output_inventory/svc_82_Container Registry.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "serviceId": 82, - "svc_code": "Container Registry", - "instances": [ - { - "uid": "55c4914e-7bc5-4bcc-bc71-2444025bc6fc", - "name": "pearlharbor", - "serviceId": 82, - "svc_code": "Container Registry", - "status": "running", - "source": "prod", - "params": { - "s3Uid": "6d6061cb-b0c1-44b9-8969-a70f08fe673c", - "domain": "pearlharbor", - "emails": "tazet@narod.ru", - "resourceCPU": 100, - "resourceRealm": "k8s-3.ext.nubes.ru", - "resourceMemory": 200, - "resourceInstances": 1 - }, - "out": { - "monitoring": { - "base": { - "url": "https://grafana.ngcloud.ru/d/55c4914e-7bc5-4bcc-bc71-2444025bc6fc-def?orgId=28" - }, - "loki": { - "url": "https://grafana.ngcloud.ru/d/55c4914e-7bc5-4bcc-bc71-2444025bc6fc-log?orgId=28" - }, - "k8sregistry": { - "url": "https://grafana.ngcloud.ru/d/55c4914e-7bc5-4bcc-bc71-2444025bc6fc-krg?orgId=28" - }, - "allDashboards": "https://grafana.ngcloud.ru/dashboards/f/55c4914e-7bc5-4bcc-bc71-2444025bc6fc?orgId=28" - }, - "connectionUrl": "https://pearlharbor.registryk8s.services.ngcloud.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_89_Web-сервер_с_фреймворком_Flask.json b/generated/test/output_inventory/svc_89_Web-сервер_с_фреймворком_Flask.json deleted file mode 100644 index 33a01c1..0000000 --- a/generated/test/output_inventory/svc_89_Web-сервер_с_фреймворком_Flask.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "serviceId": 89, - "svc_code": "Web-сервер с фреймворком Flask", - "instances": [ - { - "uid": "7E6A86A6-5F49-4A5E-BD58-DB213DBB2EA0", - "name": "inv-svc-89-1774956904", - "serviceId": 89, - "svc_code": "Web-сервер с фреймворком Flask", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "704F63C7-5F40-40A6-B274-853F6139768D", - "name": "inv-svc-89-r2", - "serviceId": 89, - "svc_code": "Web-сервер с фреймворком Flask", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "1883104F-6C0B-4491-AE4C-E7D3F621104A", - "name": "inv-svc-89-r3", - "serviceId": 89, - "svc_code": "Web-сервер с фреймворком Flask", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "63DEB1C6-52D5-4EE8-BC48-C8B66AB30AAD", - "name": "inv-flask-r4", - "serviceId": 89, - "svc_code": "Web-сервер с фреймворком Flask", - "status": "running", - "params": { - "domain": "web01", - "gitPath": "https://github.com/Foxyhhd/Baldurs-Gate-test.git", - "jsonEnv": {}, - "healthPath": "", - "resourceCPU": 300, - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "resourceMemory": 256, - "resourceInstances": 1 - }, - "out": { - "monitoring": { - "resourceMetrics": "https://grafana.ngcloud.ru/d/vzjb4zd/kubernetes-pods?orgId=954&var-namespace=63deb1c6-52d5-4ee8-bc48-c8b66ab30aad&var-resource_realm=k8s-3-sandbox-nubes-ru" - }, - "connectionUrl": "https://web01.pythonk8s.dev.nubes.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_90_PostgreSQL.json b/generated/test/output_inventory/svc_90_PostgreSQL.json deleted file mode 100644 index 689d529..0000000 --- a/generated/test/output_inventory/svc_90_PostgreSQL.json +++ /dev/null @@ -1,211 +0,0 @@ -{ - "serviceId": 90, - "svc_code": "PostgreSQL", - "instances": [ - { - "uid": "bba55e0f-4c51-4312-8ad3-efc557de331d", - "name": "pg-sless-demo", - "status": "suspended", - "params": { - "s3Uid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "autoScale": "false", - "allowNoSSL": "false", - "appVersion": "17", - "resourceCPU": 500, - "resourceDisk": "1", - "resourceRealm": "naeel-test-3", - "jsonParameters": { - "log_connections": "off", - "log_disconnections": "off" - }, - "resourceMemory": 512, - "autoScaleQuotaGb": "1", - "ipSpaceNameSlave": "", - "ipSpaceNameMaster": "", - "resourceInstances": 1, - "autoScalePercentage": "10", - "autoScaleTechWindow": "0", - "enablePgPoolerSlave": "false", - "ext_BACKUP_SCHEDULE": "0 0 * * *", - "enablePgPoolerMaster": "false", - "ext_BACKUP_NUM_TO_RETAIN": "7", - "needExternalAddressSlave": "false", - "needExternalAddressMaster": "false" - }, - "out": { - "users": { - "user0": { - "role": "ddl_user", - "username": "user0" - } - }, - "databases": { - "db0": { - "dbName": "db0", - "dbOwner": "user0" - } - }, - "monitoring": { - "base": { - "url": "https://grafana.ngcloud.ru/d/bba55e0f-4c51-4312-8ad3-efc557de331d-def?orgId=962" - }, - "loki": { - "url": "https://grafana.ngcloud.ru/d/bba55e0f-4c51-4312-8ad3-efc557de331d-log?orgId=962" - }, - "k8spostgresql": { - "url": "https://grafana.ngcloud.ru/d/bba55e0f-4c51-4312-8ad3-efc557de331d-kpg?orgId=962" - }, - "resourceMetrics": "https://grafana.ngcloud.ru/dashboards/f/bba55e0f-4c51-4312-8ad3-efc557de331d?orgId=962", - "k8spostgresqlbackup": { - "url": "https://grafana.ngcloud.ru/d/bba55e0f-4c51-4312-8ad3-efc557de331d-bpg?orgId=962" - } - }, - "externalConnect": { - "slave": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - }, - "master": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - } - }, - "internalConnect": { - "slave": "", - "master": "postgresqlk8s-master.bba55e0f-4c51-4312-8ad3-efc557de331d.svc.cluster.local" - } - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - }, - { - "uid": "f87f606f-b32e-4eb2-9563-8c3bf88a2d82", - "name": "pg4tf033", - "status": "suspended", - "params": { - "s3Uid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "autoScale": "false", - "allowNoSSL": "false", - "appVersion": "17", - "resourceCPU": 500, - "resourceDisk": "1", - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "jsonParameters": { - "log_connections": "off", - "log_disconnections": "off" - }, - "resourceMemory": 512, - "autoScaleQuotaGb": "1", - "ipSpaceNameSlave": "", - "ipSpaceNameMaster": "", - "resourceInstances": 1, - "autoScalePercentage": "10", - "autoScaleTechWindow": "0", - "enablePgPoolerSlave": "false", - "ext_BACKUP_SCHEDULE": "0 0 * * *", - "enablePgPoolerMaster": "false", - "ext_BACKUP_NUM_TO_RETAIN": "7", - "needExternalAddressSlave": "false", - "needExternalAddressMaster": "false" - }, - "out": { - "users": {}, - "databases": {}, - "monitoring": { - "resourceMetrics": "https://grafana.ngcloud.ru/d/vzjb4zd/kubernetes-pods?orgId=954&var-namespace=f87f606f-b32e-4eb2-9563-8c3bf88a2d82&var-resource_realm=k8s-3-sandbox-nubes-ru" - }, - "externalConnect": { - "slave": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - }, - "master": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - } - }, - "internalConnect": { - "slave": "", - "master": "postgresqlk8s-master.f87f606f-b32e-4eb2-9563-8c3bf88a2d82.svc.cluster.local" - } - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - }, - { - "uid": "f97978e3-9300-41bb-b22c-4f9aecf674f8", - "name": "pg4tf011", - "status": "suspended", - "params": { - "s3Uid": "332cdb0d-34bf-43bf-864d-4adcc3b556fb", - "autoScale": "false", - "allowNoSSL": "false", - "appVersion": "17", - "resourceCPU": 500, - "resourceDisk": "1", - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "jsonParameters": { - "log_connections": "off", - "log_disconnections": "off" - }, - "resourceMemory": 512, - "autoScaleQuotaGb": "1", - "ipSpaceNameSlave": "", - "ipSpaceNameMaster": "", - "resourceInstances": 1, - "autoScalePercentage": "10", - "autoScaleTechWindow": "0", - "enablePgPoolerSlave": "false", - "ext_BACKUP_SCHEDULE": "0 0 * * *", - "enablePgPoolerMaster": "false", - "ext_BACKUP_NUM_TO_RETAIN": "7", - "needExternalAddressSlave": "false", - "needExternalAddressMaster": "false" - }, - "out": { - "users": {}, - "databases": {}, - "monitoring": { - "resourceMetrics": "https://grafana.ngcloud.ru/d/vzjb4zd/kubernetes-pods?orgId=954&var-namespace=f97978e3-9300-41bb-b22c-4f9aecf674f8&var-resource_realm=k8s-3-sandbox-nubes-ru" - }, - "externalConnect": { - "slave": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - }, - "master": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - } - }, - "internalConnect": { - "slave": "", - "master": "postgresqlk8s-master.f97978e3-9300-41bb-b22c-4f9aecf674f8.svc.cluster.local" - } - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_91_Redis.json b/generated/test/output_inventory/svc_91_Redis.json deleted file mode 100644 index 132817a..0000000 --- a/generated/test/output_inventory/svc_91_Redis.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "serviceId": 91, - "svc_code": "Redis", - "instances": [ - { - "uid": "A47F8E86-7684-44A3-8319-C6801C671FC0", - "name": "inv-redis-1774955749", - "serviceId": 91, - "svc_code": "Redis", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "1A8EB2E1-30A1-41A0-A488-B03CDFBDAE63", - "name": "inv-redis-1774955832", - "serviceId": 91, - "svc_code": "Redis", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "76E0B60D-9F29-4C27-9EA3-9423608D1A98", - "name": "inv-redis-test", - "serviceId": 91, - "svc_code": "Redis", - "status": "running", - "params": { - "resourceCPU": 1000, - "resourceDisk": "30", - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "resourceMemory": 1024, - "resourceInstances": 1, - "needExternalAddressSlave": "false", - "needExternalAddressMaster": "false" - }, - "out": { - "monitoring": { - "resourceMetrics": "https://grafana.ngcloud.ru/d/vzjb4zd/kubernetes-pods?orgId=954&var-namespace=76e0b60d-9f29-4c27-9ea3-9423608d1a98&var-resource_realm=k8s-3-sandbox-nubes-ru" - }, - "externalConnect": { - "slave": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - }, - "master": { - "ip": "", - "fqdn": "", - "uuid": "", - "isExternal": false - } - }, - "internalConnect": { - "slave": "", - "master": "redisk8s.76e0b60d-9f29-4c27-9ea3-9423608d1a98.svc.k8s-3-sandbox-nubes-ru" - } - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_92_MongoDB.json b/generated/test/output_inventory/svc_92_MongoDB.json deleted file mode 100644 index 1a23746..0000000 --- a/generated/test/output_inventory/svc_92_MongoDB.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "serviceId": 92, - "svc_code": "MongoDB", - "instances": [ - { - "uid": "2DE9569A-0C17-40FD-A591-027F18658E3F", - "name": "inv-svc-92-1774956293", - "serviceId": 92, - "svc_code": "MongoDB", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "01CD4576-9DC1-42C7-8F32-B1C75CA234D8", - "name": "inv-svc-92-r3", - "serviceId": 92, - "svc_code": "MongoDB", - "status": "running", - "params": { - "resourceCPU": 1000, - "resourceDisk": "10", - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "resourceMemory": 1024, - "resourceInstances": 1, - "needExternalAddressMaster": "false" - }, - "out": { - "monitoring": { - "base": { - "url": "https://grafana.ngcloud.ru/d/01cd4576-9dc1-42c7-8f32-b1c75ca234d8-def?orgId=962" - }, - "loki": { - "url": "https://grafana.ngcloud.ru/d/01cd4576-9dc1-42c7-8f32-b1c75ca234d8-log?orgId=962" - }, - "allDashboards": "https://grafana.ngcloud.ru/dashboards/f/01cd4576-9dc1-42c7-8f32-b1c75ca234d8?orgId=962" - }, - "internalConnect": "mongok8s-psmdb-db-rs0.01cd4576-9dc1-42c7-8f32-b1c75ca234d8.svc.k8s-3-sandbox-nubes-ru" - }, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_93_RabbitMQ.json b/generated/test/output_inventory/svc_93_RabbitMQ.json deleted file mode 100644 index bd5329b..0000000 --- a/generated/test/output_inventory/svc_93_RabbitMQ.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "serviceId": 93, - "svc_code": "RabbitMQ", - "instances": [ - { - "uid": "1dbfe9da-ce1c-4958-b359-d016a4b455c8", - "name": "sless-rabbit", - "status": "running", - "params": { - "resourceCPU": 500, - "resourceDisk": "5", - "resourceRealm": "naeel-test-3", - "resourceMemory": 512, - "resourceInstances": 1, - "needExternalAddressMaster": "false" - }, - "out": { - "monitoring": { - "base": { - "url": "https://grafana.ngcloud.ru/d/1dbfe9da-ce1c-4958-b359-d016a4b455c8-def?orgId=962" - }, - "loki": { - "url": "https://grafana.ngcloud.ru/d/1dbfe9da-ce1c-4958-b359-d016a4b455c8-log?orgId=962" - }, - "resourceMetrics": "https://grafana.ngcloud.ru/dashboards/f/1dbfe9da-ce1c-4958-b359-d016a4b455c8?orgId=962" - }, - "clusterDomain": "cluster.local", - "inernalConnect": { - "slave": "", - "master": "rabbitmqk8s.1dbfe9da-ce1c-4958-b359-d016a4b455c8.svc.cluster.local" - }, - "externalConnect": { - "admin": { - "ip": "185.247.187.147", - "fqdn": "admin.1dbfe9da-ce1c-4958-b359-d016a4b455c8.dev.nubes.ru", - "uuid": "9fa09e8c-2725-4efa-ace6-83123ed5ebfc", - "isExternal": false - } - } - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_94_Lucee.json b/generated/test/output_inventory/svc_94_Lucee.json deleted file mode 100644 index b38925e..0000000 --- a/generated/test/output_inventory/svc_94_Lucee.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "serviceId": 94, - "svc_code": "Lucee", - "instances": [ - { - "uid": "86d5253c-b0fd-435c-9951-4a7d2e2f8e04", - "name": "lucy_teststand_0", - "status": "suspended", - "params": { - "domain": "web-test-stand", - "gitPath": "https://gitea-naeel.giteak8s.services.ngcloud.ru/naeel/testlucee", - "jsonEnv": { - "testds_class": "org.postgresql.Driver", - "testds_password": "zCDy6Wt6qBDXO3UlQl5ZgooxYElvY5LdBvTuiMZWLaKtDIF15uWoVM51YEZWTZHI", - "testds_username": "user0", - "testds_validate": "false", - "testds_bundleName": "org.postgresql.jdbc", - "testds_liveTimeout": "15", - "testds_bundleVersion": "42.6.0", - "testds_connectionLimit": "5", - "testds_connectionString": "jdbc:postgresql://postgresqlk8s-master.f97978e3-9300-41bb-b22c-4f9aecf674f8.svc.cluster.local:5432/postgres?sslmode=require" - }, - "appVersion": "5.4", - "healthPath": "", - "resourceCPU": 300, - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "resourceMemory": 512, - "resourceInstances": 1 - }, - "out": { - "monitoring": { - "resourceMetrics": "https://grafana.ngcloud.ru/d/vzjb4zd/kubernetes-pods?orgId=954&var-namespace=86d5253c-b0fd-435c-9951-4a7d2e2f8e04&var-resource_realm=k8s-3-sandbox-nubes-ru" - }, - "connectionUrl": "https://web-test-stand.luceek8s.dev.nubes.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_95_NodeJS.json b/generated/test/output_inventory/svc_95_NodeJS.json deleted file mode 100644 index d94bf25..0000000 --- a/generated/test/output_inventory/svc_95_NodeJS.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "serviceId": 95, - "svc_code": "NodeJS", - "instances": [ - { - "uid": "6bfdb1d0-5d32-437e-9086-b2544b39e2cd", - "name": "node_01", - "status": "suspended", - "params": { - "domain": "node07", - "gitPath": "https://gitea-naeel.giteak8s.services.ngcloud.ru/naeel/testnode.git", - "jsonEnv": { - "PGHOST": "postgresqlk8s-master.f97978e3-9300-41bb-b22c-4f9aecf674f8.svc.cluster.local", - "PGPORT": "5432", - "PGUSER": "user0", - "PGSSLMODE": "require", - "PGDATABASE": "db_terra", - "PGPASSWORD": "zCDy6Wt6qBDXO3UlQl5ZgooxYElvY5LdBvTuiMZWLaKtDIF15uWoVM51YEZWTZHI", - "DATABASE_URL": "postgresql://user0:zCDy6Wt6qBDXO3UlQl5ZgooxYElvY5LdBvTuiMZWLaKtDIF15uWoVM51YEZWTZHI@postgresqlk8s-master.f97978e3-9300-41bb-b22c-4f9aecf674f8.svc.cluster.local:5432/db_terra?sslmode=require" - }, - "appVersion": "23", - "healthPath": "/healthz", - "resourceCPU": 300, - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "resourceMemory": 256, - "resourceInstances": 1 - }, - "out": { - "monitoring": { - "resourceMetrics": "https://grafana.ngcloud.ru/d/vzjb4zd/kubernetes-pods?orgId=954&var-namespace=6bfdb1d0-5d32-437e-9086-b2544b39e2cd&var-resource_realm=k8s-3-sandbox-nubes-ru" - }, - "connectionUrl": "https://node07.nodejsk8s.dev.nubes.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_96_pgAdmin.json b/generated/test/output_inventory/svc_96_pgAdmin.json deleted file mode 100644 index 0fdd4a3..0000000 --- a/generated/test/output_inventory/svc_96_pgAdmin.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "serviceId": 96, - "svc_code": "pgAdmin", - "instances": [ - { - "uid": "6A28DD42-F374-4EAF-90FE-03833612BA28", - "name": "inv-svc-96-1774957391", - "serviceId": 96, - "svc_code": "pgAdmin", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "E5FD046C-553B-4EFD-9E8B-6A0DFD955EDB", - "name": "inv-svc-96-r2", - "serviceId": 96, - "svc_code": "pgAdmin", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "F2D61F0E-5E7E-4D9D-BD57-DC2A3F793CF5", - "name": "inv-svc-96-r3", - "serviceId": 96, - "svc_code": "pgAdmin", - "status": "running", - "params": { - "login": "admin@ngcloud.ru", - "domain": "web01", - "password": "********", - "resourceCPU": 500, - "resourceDisk": "1", - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "resourceMemory": 512, - "resourceInstances": 1 - }, - "out": { - "monitoring": { - "resourceMetrics": "https://grafana.ngcloud.ru/d/vzjb4zd/kubernetes-pods?orgId=954&var-namespace=f2d61f0e-5e7e-4d9d-bd57-dc2a3f793cf5&var-resource_realm=k8s-3-sandbox-nubes-ru" - }, - "connectionUrl": "https://web01.pgadmink8s.dev.nubes.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_97_NodeRed.json b/generated/test/output_inventory/svc_97_NodeRed.json deleted file mode 100644 index 57fe9d6..0000000 --- a/generated/test/output_inventory/svc_97_NodeRed.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "serviceId": 97, - "svc_code": "NodeRed", - "instances": [ - { - "uid": "FD777742-39B0-4C8D-8F7A-263A55C63D24", - "name": "inv-svc-97-1774956994", - "serviceId": 97, - "svc_code": "NodeRed", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "E92ECCAC-D643-4F0C-BB52-16078B1678F4", - "name": "inv-svc-97-r2", - "serviceId": 97, - "svc_code": "NodeRed", - "status": "running", - "params": { - "resourceRealm": "k8s-3-sandbox-nubes-ru" - }, - "out": {}, - "vault_keys": [] - }, - { - "uid": "0146BF85-164C-4DEA-8591-6056FECF479A", - "name": "inv-svc-97-r4", - "serviceId": 97, - "svc_code": "NodeRed", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "09D788A5-4D8D-4133-8F27-C36B6C8113EC", - "name": "inv-svc-97-r5", - "serviceId": 97, - "svc_code": "NodeRed", - "status": "running", - "params": { - "resourceRealm": "k8s-3-sandbox-nubes-ru" - }, - "out": {}, - "vault_keys": [] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_98_Простой_HTTP_контейнер.json b/generated/test/output_inventory/svc_98_Простой_HTTP_контейнер.json deleted file mode 100644 index 22b1462..0000000 --- a/generated/test/output_inventory/svc_98_Простой_HTTP_контейнер.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "serviceId": 98, - "svc_code": "Простой HTTP контейнер", - "instances": [ - { - "uid": "AF8C0CB4-AF45-4D00-A39C-1A53D8A1C843", - "name": "inv-svc-98-1774956936", - "serviceId": 98, - "svc_code": "Простой HTTP контейнер", - "status": "not created", - "params": {}, - "out": {}, - "vault_keys": [] - }, - { - "uid": "9BD1957F-BBBA-4767-970A-AA4FE4D818D6", - "name": "inv-svc-98-r2", - "serviceId": 98, - "svc_code": "Простой HTTP контейнер", - "status": "running", - "params": { - "domain": "web01", - "jsonEnv": { - "param": "value" - }, - "resourceCPU": 100, - "registryPath": "nexus-sa.tst.nubes.ru/docker-nubes/jolt", - "resourceRealm": "k8s-3-sandbox-nubes-ru", - "resourceMemory": 200, - "resourceInstances": 1 - }, - "out": { - "monitoring": { - "resourceMetrics": "https://grafana.ngcloud.ru/d/vzjb4zd/kubernetes-pods?orgId=954&var-namespace=9bd1957f-bbba-4767-970a-aa4fe4d818d6&var-resource_realm=k8s-3-sandbox-nubes-ru" - }, - "connectionUrl": "https://web01.containerk8s.dev.nubes.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/output_inventory/svc_99_Gitea.json b/generated/test/output_inventory/svc_99_Gitea.json deleted file mode 100644 index dd8baa5..0000000 --- a/generated/test/output_inventory/svc_99_Gitea.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "serviceId": 99, - "svc_code": "Gitea", - "instances": [ - { - "uid": "e15e66e1-c613-4230-8f5e-263804224b0f", - "name": "naeel_git", - "serviceId": 99, - "svc_code": "Gitea", - "status": "running", - "source": "prod", - "params": { - "domain": "gitea-naeel", - "psqlUid": "b1d8ab38-bd8a-4be4-a27c-9b1a74dc0f19", - "resourceCPU": 500, - "resourceDisk": "1", - "resourceRealm": "k8s-3.ext.nubes.ru", - "resourceMemory": 512, - "resourceInstances": 1 - }, - "out": { - "monitoring": { - "base": { - "url": "https://grafana.ngcloud.ru/d/e15e66e1-c613-4230-8f5e-263804224b0f-def?orgId=28" - }, - "loki": { - "url": "https://grafana.ngcloud.ru/d/e15e66e1-c613-4230-8f5e-263804224b0f-log?orgId=28" - }, - "allDashboards": "https://grafana.ngcloud.ru/dashboards/f/e15e66e1-c613-4230-8f5e-263804224b0f?orgId=28" - }, - "connectionUrl": "https://gitea-naeel.giteak8s.services.ngcloud.ru" - }, - "vault_keys": [ - "url", - "fields", - "userPath" - ] - } - ] -} \ No newline at end of file diff --git a/generated/test/resources_yaml/.gitkeep b/generated/test/resources_yaml/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/generated/test/resources_yaml/100_openwhisk.yaml b/generated/test/resources_yaml/100_openwhisk.yaml deleted file mode 100644 index fdc2fdc..0000000 --- a/generated/test/resources_yaml/100_openwhisk.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: openwhisk -service_id: 100 -service_display_name: Serverless Openwhisk (openwhisk_tenant) -service_short_name: openwhisk -service_man: Добавление и удаления пользователя для работы с Openwhisk -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: [] diff --git a/generated/test/resources_yaml/110_dnszone.yaml b/generated/test/resources_yaml/110_dnszone.yaml deleted file mode 100644 index 03d2540..0000000 --- a/generated/test/resources_yaml/110_dnszone.yaml +++ /dev/null @@ -1,94 +0,0 @@ -name: dnszone -service_id: 110 -service_display_name: DNS зона -service_short_name: dnszone -service_man: '## ![image](https://img.icons8.com/?size=50&id=41400&format=png) Необходимо делегировать зону у регистратора на Авторитетные DNS (Сервера зон)

ns3.ngcloud.ru
``` bash
185.247.187.83
2a10:aa80:0:5::3
```

ns4.ngcloud.ru
``` bash
81.22.46.43
2a10:aa80:0:6::3
```' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 43 - kind: instance - action: create - params: - - id: 66 - code: zoneEmail - data_type: string - required: true - descr: Контактный e-mail - - id: 67 - code: zoneName - data_type: string - required: true - regex: ^([a-z0-9-]+\.)+[a-z0-9-]+$ - descr: Имя зоны - man: Имя зоны - - id: 68 - code: zoneKind - data_type: string - required: true - default: NATIVE - value_list: - - NATIVE - - SLAVE - descr: Тип зоны - - id: 69 - code: zoneMastersForSlave - data_type: string - required: false - descr: Использовать если выбран тип SLAVE. IP адреса в формате через пробел для настройки Master-серверов - - id: 70 - code: zoneTimeToRefresh - data_type: string - required: true - default: "86400" - descr: Время ожидания ответа вторичного DNS перед запросом SOA-записи с первичных серверов - - id: 71 - code: zoneTimeToRetry - data_type: string - required: true - default: "7200" - descr: Время в течение которого сервер повторно попробует синхронизировать информацию с первичных DNS-серверов - - id: 72 - code: zoneTimeToExpire - data_type: string - required: true - default: "3600000" - descr: Время в течение которого вторичный DNS будет пытаться завершить синхронизацию зоны с первичным - - id: 73 - code: zoneTimeToLive - data_type: string - required: true - default: "86400" - descr: Время, в течение которого информация будет кешироваться другими DNS-серверами - - id: 284 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: delete - id: 44 - kind: instance - action: delete - params: [] diff --git a/generated/test/resources_yaml/111_dnsrecord.yaml b/generated/test/resources_yaml/111_dnsrecord.yaml deleted file mode 100644 index d87a3c1..0000000 --- a/generated/test/resources_yaml/111_dnsrecord.yaml +++ /dev/null @@ -1,105 +0,0 @@ -name: dnsrecord -service_id: 111 -service_display_name: DNS запись -service_short_name: dnsrecord -service_man: Необходима DNS зона, в которой будет создана DNS запись.
Выберите
* Зону в которой будет создана запись
* Тип записи
* Имя записи
* Значение записи -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 45 - kind: instance - action: create - params: - - id: 75 - code: zoneUid - data_type: uuid - required: true - ref_svc_id: 109 - descr: UUID экземпляра услуги DNS-зоны - man: UUID экземпляра услуги DNS-зоны - sort: 10 - - id: 76 - code: recordType - data_type: string - required: true - value_list: - - A - - AAAA - - CNAME - - MX - - PTR - - SOA - - SRV - - TXT - - LUA - - NS - - SSHFP - descr: Тип DNS-записи - man: Тип DNS-записи - sort: 20 - - id: 77 - code: recordName - data_type: string - required: true - unique_scope: parent - descr: Имя записи. Имя зоны в конце проставляется автоматически - man: Имя записи. Имя зоны в конце проставляется автоматически - sort: 30 - - id: 78 - code: recordInput - data_type: string - required: true - descr: Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - man: Значение. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - sort: 40 - is_modifiable: true - - id: 450 - code: recordTTL - data_type: integer > 0 - required: true - default: "3600" - maxvalue: 604800 - minvalue: 30 - descr: Time-to-Leave записи. Раз в какое время запись будет обновлена - sort: 50 - - name: delete - id: 46 - kind: instance - action: delete - params: [] - - name: modify - id: 90 - kind: instance - action: modify - params: - - id: 256 - code: recordInput - data_type: string - required: true - descr: Запись. Необходима валидация, в зависимости от типа записи. Должно быть заменено на UUID-внешнийIP - - name: reconcile - id: 408 - kind: action - action: reconcile - params: [] diff --git a/generated/test/resources_yaml/112_tenant.yaml b/generated/test/resources_yaml/112_tenant.yaml deleted file mode 100644 index a7ae715..0000000 --- a/generated/test/resources_yaml/112_tenant.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: tenant -service_id: 112 -service_display_name: Тенант в Grafana -service_short_name: tenant -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 84 - kind: instance - action: create - params: - - id: 239 - code: grafanaOrgName - data_type: string - required: true - regex: ^WZ[\d]+$ - descr: WZ-Код клиента - sort: 10 - - id: 240 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 20 - - name: delete - id: 86 - kind: instance - action: delete - params: [] - - name: modify - id: 87 - kind: instance - action: modify - man: Просто удаляет все текущие датасоурсы и ставит их заново
Полезно, когда нужно "ресетнуть" / "добавить" - params: [] diff --git a/generated/test/resources_yaml/113_vc_complex.yaml b/generated/test/resources_yaml/113_vc_complex.yaml deleted file mode 100644 index 038f922..0000000 --- a/generated/test/resources_yaml/113_vc_complex.yaml +++ /dev/null @@ -1,155 +0,0 @@ -name: vc_complex -service_id: 113 -service_display_name: Быстрый старт -service_short_name: vcComplex -service_man: '# Создает окружение для ВМ.

## Создает сервисы:
**Организация**
**Виртуальный датацентр**
**Каталог**
**Сетевой шлюз периметра**

' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 107 - kind: instance - action: create - params: - - id: 332 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование ресурсной платформы - sort: 1 - - id: 334 - code: vappName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: Имя vApp - sort: 10 - - id: 358 - code: vdcProviderGateway - data_type: string - required: true - default: sandbox-v1cl1-pvdc - descr: Взять из свойств ресурсной платформы.
Путь .vcd.providerVdc - взять KEY

providerGateway Cloud Director. Влияет ресурсы будут предоставлены. Является полем (List<String>) в свойствах рес. платформы ЛК, но сам параметр передаётся только как один String - sort: 200 - - id: 359 - code: virtualServicesCount - required: true - default: "1" - maxvalue: 4 - minvalue: 1 - descr: Кол-во виртуальных сервисов, которые выделяются на AVI. Во избежании коллапса пока выделяется до 4 - sort: 110 - - id: 360 - code: ipSpaceName - data_type: string - required: false - default: internet-ipv4-v1 - descr: Имя ip Space для внешнего IP. Целесообразнее брать самый дешёвый, так как это vip для исходящего трафика. Необходимо задавать если включен needExternalAddressSNAT - sort: 130 - - id: 399 - code: storageConfig - data_type: json - required: true - default: '[{"name": "", "size": 1024}]' - descr: Описывается как массив объектов, где описывается имя политики и её размер - sort: 210 - - id: 400 - code: vdcNetworkPool - data_type: string - required: true - default: nsxt-sandbox-geneve-np - sort: 120 - - id: 401 - code: cpuGuaranteed - data_type: integer > 0 - required: true - default: "20" - value_list: - - "20" - - "50" - - "80" - sort: 20 - - id: 402 - code: memGuaranteed - data_type: integer > 0 - required: true - default: "20" - value_list: - - "20" - - "50" - - "80" - sort: 30 - - id: 403 - code: segroupName - data_type: string - required: false - default: SEGROUP-SANDBOX-CL1-SHARED-01 - descr: Наименование segroup, в котором будут выделяться пулы на AVI - sort: 100 - - id: 404 - code: needExternalAddressSNAT - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Выделяет внешний IP на Edge. Используется для SNAT всего трафика - sort: 40 - - id: 405 - code: needEnableAVI - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включает AVI в Cloud Director - sort: 50 - - id: 566 - code: cpuAllocated - data_type: string - required: true - default: "1" - minvalue: 1 - descr: шт - sort: 21 - - id: 567 - code: memAllocated - data_type: integer > 0 - required: true - default: "10" - minvalue: 1 - descr: gb - sort: 31 - - id: 568 - code: vIPCount - data_type: integer > 0 - required: true - default: "0" - maxvalue: 20 - minvalue: 0 - descr: ш - sort: 131 diff --git a/generated/test/resources_yaml/114_gitea_complex.yaml b/generated/test/resources_yaml/114_gitea_complex.yaml deleted file mode 100644 index b18075e..0000000 --- a/generated/test/resources_yaml/114_gitea_complex.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: gitea_complex -service_id: 114 -service_display_name: Комплексная услуга по созданию gitea -service_short_name: GiteaComplex -service_man: Комплексная услуга из ["gittea", "postgres"] -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: [] diff --git a/generated/test/resources_yaml/115_mariadb.yaml b/generated/test/resources_yaml/115_mariadb.yaml deleted file mode 100644 index 60d7492..0000000 --- a/generated/test/resources_yaml/115_mariadb.yaml +++ /dev/null @@ -1,203 +0,0 @@ -name: mariadb -service_id: 115 -service_display_name: Mariadb -service_short_name: mariadb -service_man: 'Mariadb кластер. Ресурсная платформа: k8s. Автоматизация: k8s operator.
Автоматическое резервное копирование, ручное восстановление.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 138 - kind: instance - action: create - params: - - id: 877 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 878 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 879 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - is_modifiable: true - - id: 880 - code: mariadbConfiguration - data_type: map-fixed - required: true - sort: 40 - is_modifiable: true - - id: 881 - code: backupConfiguration - data_type: map-fixed - required: true - sort: 60 - is_modifiable: true - - id: 882 - code: autoscaleConfiguration - data_type: map-fixed - required: true - sort: 70 - is_modifiable: true - - name: create_database - id: 242 - kind: subresource - action: create - subresource: database - params: - - id: 734 - code: dbName - data_type: string - required: true - default: db- - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: 'Пример: `db01`' - - name: create_user - id: 243 - kind: subresource - action: create - subresource: user - params: - - id: 735 - code: username - data_type: string - required: true - default: user - regex: ^(?![0-9_])[a-zA-Z_][a-zA-Z0-9_]{0,62}$ - maxlength: 62 - minlength: 2 - descr: 'Пример: `myusername`' - sort: 10 - - id: 736 - code: password - data_type: string - required: true - maxlength: 62 - minlength: 8 - descr: Секрет будет записан в хранилище секретов и не будет отображаться публично - sort: 20 - is_sensitive: true - - id: 737 - code: dbName - data_type: array-map-fixed - required: true - default: '[{}]' - descr: Необходимо указать массив существующих баз - man: Если базы не существует - при выполнении операции вернётся ошибка - sort: 30 - - id: 738 - code: accessHosts - data_type: string - required: true - default: '%' - descr: 'Пример: `%`' - sort: 40 - - name: delete - id: 139 - kind: instance - action: delete - params: - - id: 456 - code: deleteS3Bucket - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Также удалить технический S3 Bucket с бэкапами? - sort: 10 - - name: delete_database - id: 248 - kind: subresource - action: delete - subresource: database - params: - - id: 745 - code: dbName - data_type: string - required: true - descr: ВСЕ ДАННЫЕ ВНУТРИ БД БУДУТ УДАЛЕНЫ - - name: delete_user - id: 247 - kind: subresource - action: delete - subresource: user - params: - - id: 744 - code: username - data_type: string - required: true - descr: Имя пользователя, созданное через операцию `create_user` - - name: modify - id: 142 - kind: instance - action: modify - params: - - id: 883 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 884 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 885 - code: mariadbConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 886 - code: backupConfiguration - data_type: map-fixed - required: true - sort: 40 - - id: 887 - code: autoscaleConfiguration - data_type: map-fixed - required: true - sort: 50 - - name: reconcile - id: 287 - kind: action - action: reconcile - params: [] - - name: resume - id: 141 - kind: instance - action: resume - params: [] - - name: suspend - id: 140 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/116_kafka.yaml b/generated/test/resources_yaml/116_kafka.yaml deleted file mode 100644 index b0b9c6d..0000000 --- a/generated/test/resources_yaml/116_kafka.yaml +++ /dev/null @@ -1,291 +0,0 @@ -name: kafka -service_id: 116 -service_display_name: ApacheKafka -service_short_name: kafka -service_man: '# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Идентификатор организации
Уникальный идентификатор созданной организации. Используется для всех дальнейших API-операций.

### Статус организации
Отражает текущее состояние: active, suspended, modifying, deleting.

### Параметры сети
Выходные данные при наличии ipSpaces: список выделенных внешних IP, имя ip_space, количество IP.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)**;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к этой организации.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak.

' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 148 - kind: instance - action: create - params: - - id: 461 - code: resourceInstances - data_type: integer > 0 - required: true - value_list: - - "1" - - "2" - - "3" - - "4" - - "5" - minvalue: 1 - descr: 'Пример: `2`' - sort: 20 - is_modifiable: true - - id: 462 - code: resourceMemory - data_type: integer > 0 - required: true - minvalue: 1000 - descr: 'Пример: `2048`' - sort: 30 - is_modifiable: true - - id: 463 - code: resourceCPU - data_type: integer > 0 - required: true - minvalue: 1000 - descr: 'Пример: `2000`' - sort: 40 - is_modifiable: true - - id: 464 - code: resourceDisk - data_type: integer > 0 - required: true - descr: 'Пример: `20`' - sort: 50 - is_modifiable: true - - id: 465 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`' - sort: 60 - is_modifiable: true - - id: 466 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - sort: 70 - is_modifiable: true - - id: 469 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 5 - - name: create_topic - id: 165 - kind: subresource - action: create - subresource: topic - man: '# Инструкция по управлению топиками Apache Kafka через платформу

## 1. Общая информация

---

Топик — это основная сущность в Apache Kafka, предназначенная для приёма сообщений от продюсеров и передачи их консюмерам.
Платформа позволяет создавать, удалять и изменять параметры топиков без прямого доступа к брокерам, обеспечивая удобное управление через интерфейс или API.

---

## Доступные операции

- **create_topic** — Создание топика
- **modify_topic** — Модификация топика
- **delete_topic** — Удаление топика

---

## 2. Параметры создания топика

Ниже перечислены параметры, которые необходимо указать при создании нового топика:

* **Имя топика**
Название топика.
Должно быть уникальным в пределах кластера.
Пример: `orders-events`.

* **Партиции**
Количество партиций топика.
Рекомендуется выбирать с учётом уровня параллелизма потребителей и предполагаемой нагрузки.
Пример: `6`. Здесь важно рассказать о том как происходит расчет оптимального количества
Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.

* **Реплики**
Количество реплик для каждой партиции.
Обычно равно количеству доступных брокеров или меньше.
Пример: `3`.


---

## 4. Параметры модификации топика

Для уже существующих топиков можно изменять параметры. Все параметры являются опциональными:

* **Имя топика**
Название топика.
Пример: `orders-events`.

* **Партиции**
Новое количество партиций.
Пример: `12`.

* **Реплики**
Новое количество реплик.
Пример: `2`.

---

## 5. Рекомендации

* Планируйте количество партиций с запасом — уменьшение их числа невозможно.
* Количество реплик должно соответствовать требуемому уровню отказоустойчивости, но не превышать количество брокеров.
* Изменение параметров топика в рабочем окружении может временно влиять на производительность. Рекомендуется проводить крупные изменения в периоды минимальной нагрузки.

---' - params: - - id: 523 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`' - sort: 10 - - id: 524 - code: partitions - data_type: integer > 0 - required: true - descr: Число партиций можно увеличить, но уменьшить их нельзя. - - id: 525 - code: replicas - data_type: integer > 0 - required: true - descr: Количество реплик не может привышать количество реплик брокера - sort: 20 - - name: create_user - id: 168 - kind: subresource - action: create - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 530 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - - id: 531 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`' - - id: 532 - code: operations - data_type: string - required: true - descr: 'Пример: `Create, Describe, Read, Write`' - - id: 533 - code: group - data_type: string - required: true - descr: 'Пример: `order-consumers` или `*`' - - id: 534 - code: accessHosts - data_type: string - required: true - descr: 'Пример: `192.168.1.0/24` или `*`' - - name: delete - id: 149 - kind: instance - action: delete - params: [] - - name: delete_topic - id: 167 - kind: subresource - action: delete - subresource: topic - params: - - id: 529 - code: nameTopic - data_type: string - required: true - descr: Необходимо выбрать топик, который необходимо удалить - - name: delete_user - id: 170 - kind: subresource - action: delete - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 540 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - - name: modify - id: 162 - kind: instance - action: modify - params: - - id: 501 - code: resourceInstances - data_type: integer > 0 - required: false - value_list: - - "1" - - "2" - - "3" - - "4" - - "5" - descr: 'Пример: `2`' - - id: 502 - code: resourceMemory - data_type: integer > 0 - required: false - minvalue: 1000 - descr: 'Пример: `2048`' - - id: 503 - code: resourceCPU - required: false - minvalue: 1000 - descr: 'Пример: `2000`' - - id: 504 - code: resourceDisk - data_type: integer > 0 - required: false - descr: 'Пример: `20`' - - id: 505 - code: needExternalAddressMaster - data_type: boolean - required: false - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-брокеру. Пример: `true` или `false`' - - id: 506 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - - name: modify_topic - id: 166 - kind: subresource - action: modify - subresource: topic - man: '# Инструкция по управлению топиками Apache Kafka через платформу

## 1. Общая информация

---

Топик — это основная сущность в Apache Kafka, предназначенная для приёма сообщений от продюсеров и передачи их консюмерам.
Платформа позволяет создавать, удалять и изменять параметры топиков без прямого доступа к брокерам, обеспечивая удобное управление через интерфейс или API.

---

## Доступные операции

- **create_topic** — Создание топика
- **modify_topic** — Модификация топика
- **delete_topic** — Удаление топика

---

## 2. Параметры создания топика

Ниже перечислены параметры, которые необходимо указать при создании нового топика:

* **Имя топика**
Название топика.
Должно быть уникальным в пределах кластера.
Пример: `orders-events`.

* **Партиции**
Количество партиций топика.
Рекомендуется выбирать с учётом уровня параллелизма потребителей и предполагаемой нагрузки.
Пример: `6`. Здесь важно рассказать о том как происходит расчет оптимального количества
Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.

* **Реплики**
Количество реплик для каждой партиции.
Обычно равно количеству доступных брокеров или меньше.
Пример: `3`.


---

## 4. Параметры модификации топика

Для уже существующих топиков можно изменять параметры. Все параметры являются опциональными:

* **Имя топика**
Название топика.
Пример: `orders-events`.

* **Партиции**
Новое количество партиций.
Пример: `12`.

* **Реплики**
Новое количество реплик.
Пример: `2`.

---

## 5. Рекомендации

* Планируйте количество партиций с запасом — уменьшение их числа невозможно.
* Количество реплик должно соответствовать требуемому уровню отказоустойчивости, но не превышать количество брокеров.
* Изменение параметров топика в рабочем окружении может временно влиять на производительность. Рекомендуется проводить крупные изменения в периоды минимальной нагрузки.

---' - params: - - id: 526 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`' - sort: 10 - - id: 527 - code: partitions - required: false - descr: Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - sort: 30 - - id: 528 - code: replicas - required: false - descr: Количество партиций ≤ (число брокеров). Пример `2` - sort: 20 - - name: modify_user - id: 169 - kind: subresource - action: modify - subresource: user - man: '# Инструкция по управлению пользователями Apache Kafka.

---

## 1. Общая информация

Пользователи в Apache Kafka используются для аутентификации и авторизации при подключении к кластеру.
Платформа позволяет создавать, удалять и изменять пользователей без прямого доступа к брокерам, а также настраивать права доступа к топикам и группам.
Это обеспечивает централизованное и безопасное управление доступом к ресурсам Kafka.

---

## Доступные операции

- **create_user** — Создание пользователя
- **modify_user** — Модификация пользователя
- **delete_user** — Удаление пользователя

---

## 2. Параметры создания пользователя

Ниже перечислены параметры, которые необходимо указать при создании нового пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 3. Параметры модификации пользователя

Ниже перечислены параметры, которые необходимо указать при модификации пользователя:

* **Имя пользователя**
Имя создаваемого пользователя. Используется для подключения к Kafka и настройки прав.
Пример: `username-admin`

* **Топик**
Название топика, к которому будут назначены права для данного пользователя.
Пример: `orders-events`.
Использовать маску нельзя (`orders*`), только полное название или `*`.

* **Операции**
Список разрешённых операций на указанном топике.
Пример: `Describe, Read, Write`

* **Группа**
Имя группы, которой разрешён доступ. Используется при настройке консюмер-групп.
Пример: `order-consumers`.

* **Разрешённые хосты**
Список хостов или подсетей, с которых разрешено подключение пользователя.
Пример: `192.168.1.0/24` или `*`.

---

## 4. Параметры удалении пользователя

Ниже перечислены параметры, которые необходимо указать при удалении пользователя:

* **Имя пользователя**
Имя удаляемого пользователя.
Пример: `username-admin`

## 5. Выходные параметры

После успешного создания пользователя платформа возвращает параметры, необходимые для подключения:

* **ca.crt**
Корневой сертификат (Certificate Authority), используемый для проверки подлинности сервера при TLS-подключении.
Файл содержит публичный ключ удостоверяющего центра, которому доверяют брокеры и клиенты. Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **ca.p12**
PKCS#12-хранилище с корневым сертификатом (Certificate Authority), используемое для проверки подлинности сервера при TLS-подключении.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.p12
```

* **ca.password**
Пароль для доступа к хранилищу `ca.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

* **user.crt**
Клиентский сертификат, подтверждающий личность пользователя при подключении к Kafka.
Используется совместно с приватным ключом `user.key` для аутентификации.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.crt
```

* **user.key**
Приватный ключ пользователя, применяемый для установления защищённого TLS-соединения и подтверждения подлинности.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo ''<содержание поля>'' | base64 -d > <название>.key
```

* **user.p12**
PKCS#12-хранилище с клиентским сертификатом и приватным ключом, предназначенное для аутентификации пользователя в Kafka.
Выдаеться в формате base64 для получения файла сертификата использовать команду
```bash
echo "<содержание поля>" | base64 -d > <название>.p12
```

* **user.password**
Пароль для доступа к хранилищу `user.p12`. Выдаеться в чистом виде. Раскодировать не нужно.

Эти параметры используются для настройки TLS-подключения.

---

## 6. Пример конфигурации клиента внутри кластера

Пример пода:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: kafka-4
spec:
volumes:
- name: work
emptyDir: {}
containers:
- name: kcat
image: quay.io/strimzi/kafka:latest-kafka-4.0.0
command: ["sleep", "5600"]
volumeMounts:
- name: work
mountPath: /work
restartPolicy: Never
```

Создаём под и сохраняем сертификаты:

```bash
kubectl cp user.p12 kafka-4:/work/
kubectl cp ca.p12 kafka-4:/work/
```

Создаём файлы конфигурации:

```bash
cat > /work/user-read.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

```bash
cat > /work/user-write.properties <<''EOF''
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/work/user-write.p12
ssl.keystore.password=<user.password>
ssl.truststore.type=PKCS12
ssl.truststore.location=/work/ca.p12
ssl.truststore.password=<ca.password>
EOF
```

Листинг доступных топиков:

```bash
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server kafkak8s-bootstrap-external:9093 \
--command-config /work/user-read.properties \
--list
```

Запись сообщений:

```bash
/opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--producer.config /work/user-write.properties
```

Чтение сообщений:

```bash
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server <адрес сервис брокера>:9093 \
--topic <topic> \
--from-beginning \
--group <group> \
--consumer.config /work/user-read.properties \
--max-messages 50
```

---

## 7. Пример внешнего подключения с использованием **kcat**

**Листинг топиков**

```bash
kcat -b <externalConnect.bootstrap.fqdn>:9093 \
-L \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

**Запись сообщения**

```bash
echo "hello from kcat" | kcat -P \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-write.crt \
-X ssl.key.location=./user-write.key \
-X ssl.endpoint.identification.algorithm=none
```

**Чтение сообщений**

```bash
kcat -C \
-b <externalConnect.bootstrap.fqdn>:9093 \
-t write-test \
-o beginning \
-q \
-X security.protocol=SSL \
-X ssl.ca.location=./ca.crt \
-X ssl.certificate.location=./user-read.crt \
-X ssl.key.location=./user-read.key \
-X ssl.endpoint.identification.algorithm=none
```

---


## 9. Рекомендации

* Минимизируйте набор разрешённых операций для повышения безопасности.
* Используйте отдельные учётные записи для продюсеров, консюмеров и системных сервисов.
* Ограничивайте доступ по IP или подсетям с помощью параметра **Разрешённые хосты**.
* После изменения прав или групп пользователя рекомендуется проверить подключение и доступ к топикам.

---' - params: - - id: 535 - code: nameTopic - data_type: string - required: false - descr: 'Пример: `orders-events`. Использовать маску нельзя(`orders*`), только полное название или `*`' - - id: 536 - code: operations - data_type: string - required: false - descr: 'Пример: `Create, Describe, Read, Write`' - - id: 537 - code: group - data_type: string - required: false - descr: 'Пример: `order-consumers` или `*`' - - id: 538 - code: accessHosts - data_type: string - required: false - descr: 'Пример: `192.168.1.0/24` или `*`' - - id: 539 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - sort: 10 - - name: resume - id: 161 - kind: instance - action: resume - params: [] - - name: suspend - id: 160 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/117_nifi.yaml b/generated/test/resources_yaml/117_nifi.yaml deleted file mode 100644 index 39c49bd..0000000 --- a/generated/test/resources_yaml/117_nifi.yaml +++ /dev/null @@ -1,81 +0,0 @@ -name: nifi -service_id: 117 -service_display_name: Nifi -service_short_name: nifi -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 150 - kind: instance - action: create - params: - - id: 471 - code: kafkaUid - data_type: uuid - required: true - ref_svc_id: 116 - descr: Выбрать кластер из списка - sort: 10 - - id: 472 - code: partitions - data_type: integer > 0 - required: true - descr: Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - man: 'Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.' - sort: 30 - is_modifiable: true - - id: 473 - code: replicas - data_type: integer > 0 - required: true - descr: Количество партиций ≤ (число брокеров). Пример `2` - sort: 40 - is_modifiable: true - - id: 474 - code: nameTopic - data_type: string - required: true - descr: 'Пример: `orders-events`' - sort: 20 - - name: delete - id: 151 - kind: instance - action: delete - params: [] - - name: modify - id: 154 - kind: instance - action: modify - params: - - id: 477 - code: partitions - data_type: integer > 0 - required: false - descr: Число партиций на кластер ≤ 100 × (число брокеров) × (фактор репликации). Пример `50` - man: 'Обратите внимание: уменьшить количество партиций после создания невозможно, поэтому лучше закладывать небольшой запас на будущий рост нагрузки.' - - id: 478 - code: replicas - data_type: integer > 0 - required: false - descr: Количество партиций ≤ (число брокеров). Пример `2` diff --git a/generated/test/resources_yaml/119_akhq.yaml b/generated/test/resources_yaml/119_akhq.yaml deleted file mode 100644 index 7339976..0000000 --- a/generated/test/resources_yaml/119_akhq.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: akhq -service_id: 119 -service_display_name: Akhq -service_short_name: Akhq -service_man: '# Инструкция по развертыванию Apache Kafka через платформу

---
## 1. Общая информация
AKHQ — это веб-интерфейс для работы с кластерами Apache Kafka.
Позволяет просматривать топики, consumer group''ы, сообщения, ACL, схему безопасности, состояние брокеров и метаданные.
Поддерживает работу с несколькими кластерами Kafka одновременно, включая внутренние и внешние (TLS) подключения.

## Доступные операции
- **create** — Создание ресурса AKHQ
- **suspend** — Остановка ресурса
- **resume** — Возобновление работы ресурса
- **modify** — Модификация настроек
- **delete** — Удаление ресурса

---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса Kafka:

* **Кластер Kafka к которому нужно настроить подключение**
Для использования AKHQ необходимо предварительно развернуть сервис Kafka. Пример: `kafka-external`.

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество узлов для работы Akhq. Пример `2`

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `512`

* **Квота (millicore ) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `500`

* **Имя домена:**
Dns Имя по которому будет происходить обращение к сервису. Указать необходимо уникальное имя до . ( то есть если необходимо получить dns ui) Пример: `kafka-external`

---
## 4. Выходные параметры
После успешного развертывания ресурса Kafka платформа возвращает ряд параметров.
Ключевым из них является:

**connectionUrl**
Это полное доменное имя (FQDN), по которому будет доступен интерфейс AKHQ. После развёртывания подождите несколько минут — UI станет доступен по HTTPS, как только все сервисы полностью запустятся.

**Учетные данные**
Здесь представлены поля для ввода логина и пароля, с помощью которых вы сможете авторизоваться в сервисе.

---
## 5. Дополнительная информация
Учётные записи, созданные для работы с AKHQ, предоставляют доступ только для просмотра данных. Для управления Kafka, пожалуйста, используйте возможности личного кабинета.
---' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 175 - kind: instance - action: create - params: - - id: 550 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 551 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - minvalue: 512 - descr: 'Пример: `1024`' - sort: 20 - - id: 552 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - minvalue: 500 - descr: 'Пример: `1000`' - sort: 30 - - id: 553 - code: domain - data_type: string - required: true - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 40 - - id: 554 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - minvalue: 1 - sort: 11 - - id: 555 - code: kafkaUid - data_type: uuid - required: true - ref_svc_id: 116 - descr: Выбрать кластер из списка - sort: 5 - is_modifiable: true - - name: delete - id: 176 - kind: instance - action: delete - params: [] - - name: modify - id: 180 - kind: instance - action: modify - params: - - id: 565 - code: kafkaUid - data_type: uuid - required: true - ref_svc_id: 116 - descr: Выбрать кластер из списка - - name: resume - id: 178 - kind: instance - action: resume - params: [] - - name: suspend - id: 177 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/120_clickhouse.yaml b/generated/test/resources_yaml/120_clickhouse.yaml deleted file mode 100644 index e86e6be..0000000 --- a/generated/test/resources_yaml/120_clickhouse.yaml +++ /dev/null @@ -1,211 +0,0 @@ -name: clickhouse -service_id: 120 -service_display_name: ClickHouse -service_short_name: clickhouse -service_man: '# Инструкция по управлению кластерами и пользователями ClickHouse

---

## Общая информация

ClickHouse — это колоночная система управления базами данных, предназначенная для обработки аналитических запросов в реальном времени. Платформа позволяет создавать, удалять, приостанавливать и возобновлять кластеры ClickHouse, а также управлять базами данных и пользователями.

Кластер создаётся через оператор Altinity (`https://github.com/Altinity/clickhouse-operator`) в ресурсной платформе типа `k8s`

Кластеры могут создаваться шардированными с произвольным количеством реплик. Для обеспечения отказоустойчивости и координации обязательно включение параметра `Создать ClickHouse-Keeper`.

Кластера создаются с обязательным бекапом. Для этого необходимо предварительно создать услугу `S3 Object Storage`.
---

## Доступные операции

* **create** — Создание кластера
* **delete** — Удаление кластера
* **suspend** — Приостановка работы кластера
* **resume** — Возобновление работы кластера
* **create_database** — Создание базы данных
* **delete_database** — Удаление базы данных
* **create_user** — Создание пользователя и настройка прав доступа к базе данных
* **delete_user** — Удаление пользователя

## Процесс создания и первого подключения

1. Выполнить операцию `create` - будет создан кластер
2. Выполнить операцию `create_database` - будет создана база данных
3. Выполнить операцию `create_user` - будет создан пользователь (выбрать доступ подключения к БД, созданной в п.2)

## Примеры подключения

### Подключение через HTTP-интерфейс

```bash
# Проверка доступности кластера
curl "http://<username>:<password>@<host>:8123/" -d "SELECT 1"

# Выполнение запроса
curl "http://<username>:<password>@<host>:8123/" -d "SHOW DATABASES"
```

## Простые кейсы
*Создать БД и обычной таблицы*
```clickhouse
CREATE TABLE database.table
(
id UInt64,
value String
)
ENGINE = MergeTree()
ORDER BY id;

INSERT INTO database.table SELECT number, toString(number) FROM numbers(10000000);

SELECT count() FROM database.table;
```
Базы и таблицы не реплицируются без специального ключа (`ON CLUSTER ''clickhousek8s''`)
В случае создания в стиле, описанным выше, необходимо будет выполнять действия на всех шардах/репликах


*Создание БД и шардированной таблицы*
```clickhouse
CREATE TABLE database.localUsers
(
id UInt64,
value String
)
ENGINE = MergeTree()
ORDER BY id;

CREATE TABLE database.shardedTable
AS localUsers
ENGINE = Distributed(''clickhousek8s'', ''database'', ''localUsers'', id);

INSERT INTO shardedTable SELECT number, toString(number) FROM numbers(10000000);

SELECT count() FROM shardedTable;
```
Важный момент - в данном примере таблицы придётся также выполнять на всех нодах ClickHouse

*Создание реплицируемой и шардированной таблицы*
```clickhouse
CREATE TABLE IF NOT EXISTS database.localUsers ON cluster ''clickhousek8s''
(
user_id UInt64,
name String,
email String
)
ENGINE = ReplicatedMergeTree(
''/clickhouse/tables/{shard}/localUsers'',
''{replica}''
)
ORDER BY user_id;

CREATE TABLE IF NOT EXISTS database.users ON cluster ''clickhousek8s''
AS database.localUsers
ENGINE = Distributed(''clickhousek8s'', ''database'', ''localUsers'', rand());

INSERT INTO database.users VALUES (1, ''Alice'', ''alice@example.com'');
INSERT INTO database.users VALUES (2, ''Bob'', ''bob@example.com'');
INSERT INTO database.users VALUES (3, ''Charlie'', ''charlie@example.com'');
INSERT INTO database.users VALUES (4, ''David'', ''david@example.com'');
INSERT INTO database.users VALUES (5, ''Gosha'', ''gosha@example.com'');
INSERT INTO database.users VALUES (6, ''Eve'', ''eve@example.com'');
INSERT INTO database.users VALUES (7, ''Frank'', ''frank@example.com'');
INSERT INTO database.users VALUES (8, ''Grace'', ''grace@example.com'');
INSERT INTO database.users VALUES (9, ''Hannah'', ''hannah@example.com'');
INSERT INTO database.users VALUES (10, ''Ivan'', ''ivan@example.com'');

SELECT * FROM database.localUsers;
SELECT * FROM database.users;

SELECT COUNT(*) AS total_users FROM database.users;
SELECT COUNT(*) AS total_users_local FROM database.localUsers;
```' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 181 - kind: instance - action: create - man: Операция создания кластера ClickHouse

Для подключения к кластеру также необходимо создать базу данных через операцию `create_database` и создание пользователя через операцию `create_user` - params: - - id: 837 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 838 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 839 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 40 - is_modifiable: true - - id: 840 - code: clickhouseKeeperConfiguration - data_type: map-fixed - required: true - sort: 30 - is_modifiable: true - - id: 841 - code: clickhouseConfiguration - data_type: map-fixed - required: true - sort: 50 - is_modifiable: true - - id: 842 - code: backupConfiguration - data_type: map-fixed - required: true - sort: 70 - is_modifiable: true - - id: 843 - code: autoscaleConfiguration - data_type: map-fixed - required: true - sort: 80 - is_modifiable: true - - id: 851 - code: clickhouseFilesConfiguration - data_type: array-map-fixed - required: false - man: 'Формат:
- path: somethings3.xml
xmlConfig: ''<clickhouse>......</clickhouse>''' - sort: 60 - is_modifiable: true - - name: create_database - id: 186 - kind: subresource - action: create - subresource: database - man: База данных создаётся на всех репликах кластера ClickHouse - params: - - id: 600 - code: dbName - data_type: string - required: true - default: db01 - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: 'Пример: `db01`' - sort: 10 - - name: create_user - id: 185 - kind: subresource - action: create - subresource: user - params: - - id: 596 - code: username - data_type: string - required: true - default: myusername - regex: ^(?![0-9_])[a-zA-Z_][a-zA-Z0-9_]{0,62}$ - maxlength: 62 - minlength: 2 - descr: 'Пример: `myusername`' - sort: 10 - - id: 598 - code: dbName - data_type: array-map-fixed - required: true - default: '[{}]' - sort: 30 - - id: 599 - code: accessHosts - data_type: string - required: true - default: ::/0 - descr: 'Пример: `::/0`' - sort: 40 - - name: delete - id: 184 - kind: instance - action: delete - man: Удаление возможно только после остановки сервиса через операцию `suspend`
После выполнения операции необходимо выждать определенное кол-во времени - params: [] - - name: delete_database - id: 188 - kind: subresource - action: delete - subresource: database - man: Необратимое действие!!!
Трижды подумай, заблокируй телефон тимлида и не выполняй это действие - params: - - id: 602 - code: dbName - data_type: string - required: true - descr: ВСЕ ДАННЫЕ ВНУТРИ БД БУДУТ УДАЛЕНЫ - - name: delete_user - id: 187 - kind: subresource - action: delete - subresource: user - params: - - id: 601 - code: username - required: true - descr: Имя пользователя, созданное через операцию `create_user` - - name: modify - id: 189 - kind: instance - action: modify - params: - - id: 844 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 845 - code: clickhouseKeeperConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 846 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 847 - code: clickhouseConfiguration - data_type: map-fixed - required: true - sort: 40 - - id: 848 - code: backupConfiguration - data_type: map-fixed - required: true - sort: 60 - - id: 849 - code: autoscaleConfiguration - data_type: map-fixed - required: true - sort: 70 - - id: 850 - code: clickhouseFilesConfiguration - data_type: array-map-fixed - required: false - man: 'Формат:
- path: somethings3.xml
xmlConfig: ''<clickhouse>......</clickhouse>''' - sort: 50 - - name: reconcile - id: 276 - kind: action - action: reconcile - params: [] - - name: resume - id: 183 - kind: instance - action: resume - params: [] - - name: suspend - id: 182 - kind: instance - action: suspend - man: Операция приводит к удалению всех подов
Persistent Volume остаются нетронутыми - params: [] diff --git a/generated/test/resources_yaml/12_s3.yaml b/generated/test/resources_yaml/12_s3.yaml deleted file mode 100644 index de81099..0000000 --- a/generated/test/resources_yaml/12_s3.yaml +++ /dev/null @@ -1,127 +0,0 @@ -name: s3 -service_id: 12 -service_display_name: S3 Object Storage -service_short_name: s3 -service_man: Руководство доступно по ссылке:
https://docs.s3.msk-1.ngcloud.ru/s3/s3.description.html -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 1 - kind: instance - action: create - params: - - id: 163 - code: resourceRealm - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: кластер S3 для подключения - sort: 20 - - id: 320 - code: displayName - data_type: string - required: true - regex: ^[a-zA-Z0-9_]{1,61}[a-zA-Z0-9]$ - descr: Человеко-читаемое имя (транслит из Elma) - передаётся имя клиента - sort: 10 - - name: create_sub_user - id: 6 - kind: subresource - action: create - subresource: sub_user - params: - - id: 60 - code: subUserName - data_type: string - required: true - - id: 61 - code: subUserAccess - data_type: string - required: true - value_list: - - read - - write - - readwrite - - full - - name: delete - id: 5 - kind: instance - action: delete - params: [] - - name: delete_sub_user - id: 7 - kind: subresource - action: delete - subresource: sub_user - params: - - id: 63 - code: subUserName - data_type: string - required: true - descr: subUserName. По идее услуга уже создана - должен передаваться из ЛК - - name: modify - id: 4 - kind: instance - action: modify - man: При первичном вызове операции услуга Trial прекращает действие - params: - - id: 50 - code: maxSizeGbPerUser - data_type: integer > 0 - required: false - maxvalue: 50000 - minvalue: 1 - descr: maxSizeGb. Передаём руками - man: maxSizeGb. Передаём руками - - id: 51 - code: maxObjectsPerBucket - data_type: integer > 0 - required: false - maxvalue: 1e+07 - minvalue: 1 - descr: Квота на бакет. Кол-во объектов. Передаём руками - man: Квота на бакет. Кол-во объектов. Передаём руками - - id: 52 - code: maxBucketsPerUser - data_type: integer > 0 - required: false - maxvalue: 1000 - minvalue: 1 - descr: Квота на пользователя. Количество бакетов пользователя. Передаём руками - man: Квота на пользователя. Количество бакетов пользователя. Передаём руками - - name: reconcile - id: 407 - kind: action - action: reconcile - params: [] - - name: resume - id: 3 - kind: instance - action: resume - params: [] - - name: suspend - id: 2 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/13_s3bucket.yaml b/generated/test/resources_yaml/13_s3bucket.yaml deleted file mode 100644 index 68e506c..0000000 --- a/generated/test/resources_yaml/13_s3bucket.yaml +++ /dev/null @@ -1,90 +0,0 @@ -name: s3bucket -service_id: 13 -service_display_name: S3 бакет -service_short_name: s3bucket -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 51 - kind: instance - action: create - params: - - id: 124 - code: s3UserUid - data_type: uuid - required: true - ref_svc_id: 12 - descr: UID Корневой услуги S3. На основе него будет создан бакет. - - id: 125 - code: bucketName - data_type: string - required: true - descr: Имя бакета s3 - - id: 126 - code: maxSize - required: true - default: "-1" - descr: Максимальный размер бакета s3. Если поставить -1, будет безлимит. Размер указывается в Bytes - man: Максимальный размер бакета s3. Если поставить 0, будет безлимит. Размер указывается в Bytes - - id: 127 - code: readAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ на чтение позволяет любому пользователю интернета скачивать объекты из бакета. - - id: 128 - code: listAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ к листингу позволяет любому пользователю интернета получить список объектов в бакете. - - id: 129 - code: corsAll - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Публичный доступ к чтению настроек позволяет любому пользователю интернета читать конфигурации CORS - - id: 130 - code: placement - data_type: string - required: true - default: HOT - value_list: - - HOT - - COLD - descr: Класс хранилища, который используется по умолчанию при загрузке объектов. Чем холоднее, тем дешевле место, но дороже обращения - - name: delete - id: 52 - kind: instance - action: delete - params: [] diff --git a/generated/test/resources_yaml/149_valo_tenant.yaml b/generated/test/resources_yaml/149_valo_tenant.yaml deleted file mode 100644 index ddb0afb..0000000 --- a/generated/test/resources_yaml/149_valo_tenant.yaml +++ /dev/null @@ -1,98 +0,0 @@ -name: valo_tenant -service_id: 149 -service_display_name: VALO Cloud -service_short_name: valoTenant -service_man: '# Инструкция по развертыванию Тенант Valo через платформу

## 1. Общая информация
Тенант Valo — логический изолированный экземпляр сервиса VALO Cloud, предоставляющий защищённое облачное хранилище, синхронизацию данных и доступ к документам с различных устройств. При создании тенант автоматически разворачивается в тестовом режиме сроком на 2 месяца. Перевод в промышленную эксплуатацию выполняется отдельной операцией.

### Доступные операции

* **create** — создание нового тенанта в тестовом режиме сроком на 2 месяца.
* **modify** — изменение настроек тенанта, включая перевод из ТЕСТ в ПРОД.
* **suspend** — выключение (приостановка работы) тенанта.
* **resume** — включение ранее приостановленного тенанта.
* **delete** — удаление тенанта; доступно только после выполнения операции suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создан тенант.
Пример значения: `valo.ngcloud.ru`.

### DNS-Префикс
Описание: Будет добавлено в зону valo.ngcloud.ru
Пример значения: `mysimpledomain`.

### Параметры хранилища
Описание: Сколько места будет выделено под использование в тенанте. Данные хранятся в S3. Размер указывается в Gigabytes
Пример значения: `10`.

### Настройки тенанта
Описание: Ряд конфигурации Valo-тенанта, такие как настройки пользователя и доступного функционала
Пример значения: `опционально в рамках настройки`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
Достаточно развернуть тенант в ТЕСТ. Срок предоставляется в 2 месяца. По истечению срока тенант автоматически переводится в `suspend` на стороне ресурсной платформы

### Промышленное окружение
Для разблокировки используйте операцию `modify`

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Статус тенанта
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация
Тенант всегда создаётся в режиме ТЕСТ и не может быть сразу переведён в ПРОД без операции modify.
Удаление тенанта возможно только после его выключения с помощью операции suspend.
Срок тестового режима составляет 2 месяца с момента создания.
Операции suspend и resume используются для временного управления доступностью сервиса без потери конфигурации.
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 202 - kind: instance - action: create - params: - - id: 655 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - sort: 10 - - id: 656 - code: domain - data_type: string - required: true - regex: ^[a-z0-9](?:[a-z0-9-]{3,61}[a-z0-9])?$ - maxlength: 61 - minlength: 3 - descr: Будет добавлено в зону valo.ngcloud.ru - sort: 20 - - id: 657 - code: valoOptions - data_type: map-fixed - required: true - default: '{}' - sort: 40 - is_modifiable: true - - id: 658 - code: s3Storage - data_type: integer > 0 - required: true - default: "10" - maxvalue: 999 - minvalue: 1 - descr: Параметр указывается в `Gb` - man: Данные хранятся в отдельном экземпляре S3 - sort: 30 - is_modifiable: true - - name: delete - id: 206 - kind: instance - action: delete - params: [] - - name: modify - id: 203 - kind: instance - action: modify - params: - - id: 659 - code: valoOptions - data_type: map-fixed - required: true - sort: 10 - - id: 660 - code: s3Storage - data_type: integer > 0 - required: true - descr: Параметр указывается в `Gb` - man: Данные хранятся в отдельном экземпляре S3 - sort: 20 - - name: resume - id: 205 - kind: instance - action: resume - params: [] - - name: suspend - id: 204 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/150_k8s_sthutrval_cluster.yaml b/generated/test/resources_yaml/150_k8s_sthutrval_cluster.yaml deleted file mode 100644 index 6352528..0000000 --- a/generated/test/resources_yaml/150_k8s_sthutrval_cluster.yaml +++ /dev/null @@ -1,132 +0,0 @@ -name: k8s_sthutrval_cluster -service_id: 150 -service_display_name: Kubernetes кластер Штурвал -service_short_name: k8sSthutrvalCluster -service_man: Перед разворачиванием убедиться, что в облаке есть 2 свободных невыделенных IP в пуле -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 108 - kind: instance - action: create - params: - - id: 750 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 751 - code: controlPlaneConfiguration - data_type: map-fixed - required: true - sort: 30 - is_modifiable: true - - id: 752 - code: workerConfiguration - data_type: array-map-fixed - required: true - default: '[{}]' - sort: 40 - is_modifiable: true - - id: 753 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 50 - is_modifiable: true - - id: 755 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - name: create_user - id: 281 - kind: subresource - action: create - subresource: user - params: - - id: 869 - code: admins - data_type: array-map-fixed - required: true - default: '[{}]' - sort: 10 - - name: delete - id: 109 - kind: instance - action: delete - params: [] - - name: delete_user - id: 282 - kind: subresource - action: delete - subresource: user - params: - - id: 870 - code: admins - data_type: array-map-fixed - required: true - sort: 10 - - name: modify - id: 110 - kind: instance - action: modify - man: При изменении кол-ва узлов, удаления группы, если в этой группе есть поды на которых есть PV с named-дисками, удаляться ноды сами НЕ БУДУТ.
Убедитесь, что они будут смигрированы на другие ноды в процессе прежде чем группа узлов/узлы будут удалены - params: - - id: 756 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 757 - code: controlPlaneConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 758 - code: workerConfiguration - data_type: array-map-fixed - required: true - sort: 30 - - id: 759 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 40 - - name: reconcile - id: 253 - kind: action - action: reconcile - params: [] - - name: resume - id: 174 - kind: instance - action: resume - params: [] - - name: suspend - id: 173 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/19_vc_org.yaml b/generated/test/resources_yaml/19_vc_org.yaml deleted file mode 100644 index c559f8f..0000000 --- a/generated/test/resources_yaml/19_vc_org.yaml +++ /dev/null @@ -1,108 +0,0 @@ -name: vc_org -service_id: 19 -service_display_name: Организация в Cloud Director -service_short_name: vcOrg -service_man: '# Инструкция по развертыванию Организация в Cloud Director через платформу

## 1. Общая информация

Сервис **Организация в Cloud Director** предназначен для управления изолированными организационными единицами (тенантами) внутри инфраструктуры Cloud Director. Он обеспечивает создание, модификацию и администрирование организаций, предоставление им облачных ресурсов, а также контроль уровня доступа. Сервис используется для организации рабочих окружений потребителей, управления жизненным циклом организаций и их сетевой инфраструктурой.

### Доступные операции

**create** — Создание новой организации с заданными характеристиками и типом доступа.
**delete** — Удаление организации после перехода в состояние suspend; приводит к удалению всех связанных сущностей.
**modify** — Изменение параметров внутри организации (на текущий момент поддерживается изменение ipSpaces).
**suspend** — Заморозка организации, ограничение возможности изменения и добавления сущностей.
**resume** — Разморозка организации, восстановление функций управления.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Платформа для развертывания
Описание: платформа, на которой будет создана организация.
Пример значения: `ngcloud.ru`.

### Тип организации
Описание: тип создаваемой организации.
Варианты:
- `iaas` — организация с прямым доступом к облаку и авторизацией через Keycloak.
- `saas` — организация под управлением Nubes, без прямого доступа к облаку.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Тип организации: `iaas` для обеспечения полного доступа к облачным ресурсам и самостоятельного управления.

### Промышленное окружение
- Тип организации: `saas` (упрощённая модель использования).

---

## 4. Выходные параметры

Услуга предоставляет следующие выходные параметры (формируются в процессе операций):

### Url организации
Для быстрого доступа в тенант

### Статус организации
Отражает текущее состояние и параметры.

---

## 5. Дополнительная информация

- Для конфигурации внешних IP внутри организации необходимо предварительно создать:
-- хотя бы один **Виртуальный датацентр (VDC)** привязанный к этой организации;
-- хотя бы один **Сетевой шлюз периметра (Edge Gateway)**, привязанный к vdc выше.
- Удаление организации возможно только через 14 дней после перевода в состояние suspend.
- Удаление организации приводит к удалению всех связанных сущностей: VDC, Edge Gateway, пулов IP, сетей, ВМок и иных объектов.
- Операция suspend не останавливает виртуальные машины, но блокирует любые изменения инфраструктуры внутри организации.
- Для iaas-организаций доступ осуществляется через Keycloak.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 136 - kind: instance - action: create - man: '`IaaS` - Доступ в Keycloak предоставляется пользователю, который создаёт услугу
`SaaS` - Без доступа к Keycloak' - params: - - id: 418 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Облако в котором будет развёрнут тенант - man: Выбрать платформу из списка

**Если список не отображается**
обратитесь к сервис менеджеру с вопросом предоставления ресурсной платформы - sort: 10 - - id: 556 - code: organizationType - data_type: string - required: true - default: iaas - value_list: - - iaas - - saas - man: Доступ к организации предоставляется только при выборе `iaas` - sort: 20 - - name: create_user - id: 283 - kind: subresource - action: create - subresource: user - params: - - id: 871 - code: admins - data_type: array-map-fixed - required: true - default: '[{}]' - sort: 10 - - name: delete - id: 137 - kind: instance - action: delete - man: 'Удалить возможно только через 14 дней после выполнения операции `suspend`
**ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого тенанта**

Если существуют инстансы VDC, Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов' - params: [] - - name: delete_user - id: 284 - kind: subresource - action: delete - subresource: user - params: - - id: 872 - code: admins - data_type: array-map-fixed - required: true - sort: 10 - - name: modify - id: 207 - kind: instance - action: modify - man: Для возможности изменения параметров предварительно необходимо создать **Виртуальный датацентр (VDC)**, потом **Сетевой шлюз периметра (Edge Gateway)**
Также при удалении ipSpaces убедитесь, что все внешние IP удалены. В случае если хоть одна привязка vIP есть, данный ipSpace удалён **не будет** - params: - - id: 662 - code: vIPConfigure - data_type: array-map-fixed - required: true - sort: 10 - - name: reconcile - id: 249 - kind: action - action: reconcile - params: [] - - name: resume - id: 144 - kind: instance - action: resume - params: [] - - name: suspend - id: 143 - kind: instance - action: suspend - man: Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри тенанта - params: [] diff --git a/generated/test/resources_yaml/1_dummy.yaml b/generated/test/resources_yaml/1_dummy.yaml deleted file mode 100644 index 4282a36..0000000 --- a/generated/test/resources_yaml/1_dummy.yaml +++ /dev/null @@ -1,212 +0,0 @@ -name: dummy -service_id: 1 -service_display_name: Болванка -service_short_name: dummy -service_man: '## Болванка для тестов.

А это просто много букв, чтобы посмотреть, как ведет себя текст при переполнении контейнера.


``` json
{
"iamServiceUrl": "https://auth-api-test.ngcloud.ru/api/v1/user",
"idpResponse": {
"prefix": {
"charset": "",
"status_text": "Request Time-out",
"text": true,
"errordetail": "",
"filecontent": "Connection Timeout",
"responseheader": {},
"header": "",
"statuscode": "408 Request Time-out",
"status_code": 408,
"mimetype": "Unable to determine MIME type of file."
}
}
}
```' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 18 - kind: instance - action: create - man: Это мануал к операции CREATE сервиса Болванка - params: - - id: 198 - code: durationMs - data_type: integer >= 0 - required: true - default: "0" - descr: перед завершением подождать (sleep) столько миллисекунд - man: перед завершением подождать (sleep) столько миллисекунд - sort: 20 - is_modifiable: true - - id: 199 - code: failAtStart - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, завершить джоб, ничего не записывая в cmdb - man: '**Операция не будет завершена**
Она будет в постоянном статусе PENDING, однако в Jenkins Job завершится с ошибкой' - sort: 30 - is_modifiable: true - - id: 200 - code: failInProgress - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - man: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - sort: 40 - is_modifiable: true - - id: 201 - code: whereFail - data_type: integer > 0 - required: false - default: "1" - value_list: - - "1" - - "2" - - "3" - descr: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - man: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - sort: 50 - is_modifiable: true - - id: 242 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование ресурсной платформы для подключения - sort: 10 - - id: 286 - code: bodymessage - data_type: string - required: false - descr: Дата, уходящая в Vault - man: Дата, уходящая в Vault - sort: 60 - is_modifiable: true - - id: 321 - code: mapExample - data_type: map - required: false - is_modifiable: true - - id: 322 - code: jsonExample - data_type: json - required: false - descr: Для тестирования интерфейса - man: Для тестирования интерфейса. Сюда можно писать корректный json - is_modifiable: true - - id: 396 - code: nestedRefExample - required: false - - id: 647 - code: mapFixed - data_type: map-fixed - required: false - descr: Новый тип поля - - id: 654 - code: arrayMapFixedExample - data_type: array-map-fixed - required: false - descr: Array of map-fixed - - id: 863 - code: arr - data_type: array - required: true - value_list: - - test - - "2" - - val1 - - name: delete - id: 71 - kind: instance - action: delete - params: [] - - name: modify - id: 92 - kind: instance - action: modify - params: - - id: 287 - code: durationMs - data_type: integer >= 0 - required: true - default: "0" - descr: перед завершением подождать (sleep) столько миллисекунд - man: перед завершением подождать (sleep) столько миллисекунд - sort: 10 - - id: 288 - code: failAtStart - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, завершить джоб, ничего не записывая в cmdb - sort: 20 - - id: 289 - code: failInProgress - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: если true, корректно начать выполнение джоба, но в процессе завершить аварийно, ничего не записывая в cmdb - sort: 30 - - id: 290 - code: whereFail - data_type: integer > 0 - required: false - value_list: - - "1" - - "2" - - "3" - descr: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - man: принимает 1,2,3. Работает с failInProgress. 1 - упасть в prepare. 2 - упасть внутри блока Data fill. 3 - упасть после vault write - sort: 40 - - id: 291 - code: bodymessage - required: false - descr: Дата, уходящая в Vault - man: Дата, уходящая в Vault - sort: 50 - - id: 373 - code: mapExample - data_type: map - required: false - default: '{}' - - id: 374 - code: jsonExample - required: false - - name: reconcile - id: 257 - kind: action - action: reconcile - params: [] - - name: redeploy - id: 240 - kind: action - action: redeploy - params: [] - - name: resume - id: 94 - kind: instance - action: resume - params: [] - - name: suspend - id: 93 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/20_vc_org_saas.yaml b/generated/test/resources_yaml/20_vc_org_saas.yaml deleted file mode 100644 index 1520bdf..0000000 --- a/generated/test/resources_yaml/20_vc_org_saas.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: vc_org_saas -service_id: 20 -service_display_name: Организация [DEPRECATED] -service_short_name: vcOrgSaas -service_man: 'Верхнеуровневая сущность создаваемая для Заказчика.
Внутри Организация вы можете создать: Виртуальные датацентры, Каталоги.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 8 - kind: instance - action: create - man: Создание организации в Cloud Director
Id в клауд директоре создаётся на основе contragentCode - params: - - id: 185 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование ресурсной платформы - sort: 30 - - name: delete - id: 23 - kind: instance - action: delete - params: [] - - name: resume - id: 119 - kind: instance - action: resume - params: [] - - name: suspend - id: 118 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/21_vc_vdc.yaml b/generated/test/resources_yaml/21_vc_vdc.yaml deleted file mode 100644 index 71e4ae3..0000000 --- a/generated/test/resources_yaml/21_vc_vdc.yaml +++ /dev/null @@ -1,142 +0,0 @@ -name: vc_vdc -service_id: 21 -service_display_name: Виртуальный датацентр (vDC) -service_short_name: vc_vdc -service_man: '# Инструкция по развертыванию Виртуальный датацентр (vDC) через платформу

## 1. Общая информация

**Виртуальный датацентр (vDC)** — это логическая изолированная среда в VMware Cloud Director, предназначенная для размещения и управления виртуальными машинами, сетевой инфраструктурой и ресурсами хранения. Сервис обеспечивает выделение вычислительных ресурсов под конкретную организацию и предоставляет гибкие параметры масштабирования, контроля потребления и разделения ресурсов.

### Доступные операции

**create** — Создание виртуального датацентра (vDC) с заданными параметрами CPU, RAM, Storage и сетевой конфигурацией.
**delete** — Удаление vDC. Требуется предварительный перевод vDC в состояние *suspend*. Полное удаление возможно через 14 дней.
**modify** — Внесение изменений в параметры ресурсов (CPU/RAM/Storage), выделенных для vDC.
**suspend** — Заморозка vDC. Новые ресурсы или изменения внутри vDC становятся невозможными, работа ВМ не останавливается.
**resume** — Разморозка vDC. Восстановление возможности управления сущностями внутри vDC.

---

## 2. Параметры развертывания

Ниже перечислены входные параметры операции **create**.

### UUID Организации
Уникальный идентификатор организации в Cloud Director. Перед созданием vDC требуется предварительное создание услугу `Организация в Cloud Director`.

### Provider VDC в Cloud Director
Свойство ресурсной платформы, определяющее, какой пул физических ресурсов будет использоваться.

### Network Pool в Cloud Director
Определяет возможности сетевой конфигурации, включая создание Edge Gateway и выход во внешние сети.

### Гарантированная доля ЯДЕР
Гарантированный процент вычислительных ресурсов (CPU), закрепленный за vDC. Значение устанавливается разово при создании.

### Гарантированная доля ОЗУ
Гарантированный процент оперативной памяти, закрепленный за vDC. Также задаётся один раз при создании.

### Сколько аллоцировать на VDC ЯДЕР
Количество виртуальных ядер, выделяемых в рамках vDC.

### Сколько аллоцировать на VDC ОЗУ
Количество оперативной памяти в GB, выделяемой для vDC.

### Конфигурация Storage
Набор дисковых политик и их объёмов, выделяемых для vDC. Указывается имя политики и требуемый размер (GB).

---

## 3. Рекомендованные характеристики

### Тестовое окружение

- Количество ядер CPU: 10–20
- Аллоцируемая RAM: 16–64 GB
- Гарантированная доля CPU: 20%
- Гарантированная доля RAM: 20%
- Storage:
- Политика `SATA`
- Объём: 100–300 GB

### Промышленное окружение

- Количество ядер CPU: 16–128
- Аллоцируемая RAM: 64–512 GB
- Гарантированная доля CPU: 50%
- Гарантированная доля RAM: 50%
- Storage:
- Политики уровня `SSD`
- Объём: 1–10 TB, выбор несколько политик под разные нагрузки

---

## 4. Выходные параметры

Выходные параметры формируются операцией **create** (и используются другими операциями):

### Имя vDC
Уникальный идентификатор созданного виртуального датацентра. Используется в дальнейших операциях (modify, suspend, delete).

### Параметры выделенных ресурсов
Подтверждение итогового объёма CPU/RAM/Storage, выделенных vDC. Используются для учёта и контроля потребления.

---

## 5. Дополнительная информация

- Перед созданием vDC необходимо обеспечить наличие корректно созданной организации и доступных пула ресурсов ресурсной платформы.
- Гарантированная доля CPU и RAM задаётся **однократно при создании vDC**. После развертывания изменить эти значения невозможно; для изменения необходимо пересоздать vDC.
- Удаление vDC возможно только через **14 дней после перевода в состояние *suspend***. Удаление очищает все связанные сущности (ВМ, сети, каталоги), поэтому необходимо убедиться, что данные перенесены.
- Платформа Cloud Director использует концепцию изолированных организационных ресурсов, поэтому корректная настройка Provider VDC и Network Pool является обязательной при создании vDC.
- При изменении параметров (modify) изменяются только показатели CPU, RAM и Storage. Сетевые параметры и гарантированные доли остаются неизменными.
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 9 - kind: instance - action: create - params: - - id: 30 - code: organizationUid - data_type: uuid - required: true - ref_svc_id: 19 - man: Для создания VDC предварительно необходимо создать организацию через услугу `Организация в Cloud Director` - sort: 10 - - id: 335 - code: providerVdc - data_type: string - required: true - man: Приписка `2.8` - Скорость vCPU - 2800MHz
И так далее...
- sort: 30 - depends_on: organizationUid,networkProvider - - id: 361 - code: storageConfig - data_type: array-map-fixed - required: true - default: '[{}]' - man: Первая политика в списке указывается как "По умолчанию" - sort: 100 - is_modifiable: true - - id: 397 - code: cpuGuaranteed - data_type: integer > 0 - required: true - default: "20" - value_list: - - "20" - - "50" - - "80" - descr: '% резервирования' - man: Свойство нельзя изменить после создания - sort: 60 - - id: 557 - code: cpuAllocated - data_type: integer > 0 - required: true - default: "80" - maxvalue: 1000 - minvalue: 1 - descr: шт - sort: 80 - is_modifiable: true - - id: 558 - code: memAllocated - data_type: integer > 0 - required: true - default: "200" - maxvalue: 4096 - minvalue: 1 - descr: gb - sort: 90 - is_modifiable: true - - id: 746 - code: networkProvider - data_type: string - required: true - sort: 20 - depends_on: organizationUid - - name: delete - id: 24 - kind: instance - action: delete - man: 'Удалить возможно только через 14 дней после выполнения операции `suspend`
**ОСТОРЖНО: Удаление приводит к полному удалению всех сущностей внутри этого VDC**

Если существуют инстансы Edge, vApp, Vm или Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут. Необходимо обратиться к `технической поддержке` для удаления инстансов' - params: [] - - name: modify - id: 112 - kind: instance - action: modify - params: - - id: 560 - code: cpuAllocated - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: шт - sort: 10 - - id: 561 - code: memAllocated - data_type: integer > 0 - required: true - maxvalue: 1024 - minvalue: 1 - descr: gb - sort: 20 - - id: 562 - code: storageConfig - data_type: array-map-fixed - required: true - man: Первая политика в списке указывается как "По умолчанию" - sort: 30 - - name: reconcile - id: 250 - kind: action - action: reconcile - params: [] - - name: resume - id: 172 - kind: instance - action: resume - params: [] - - name: suspend - id: 171 - kind: instance - action: suspend - man: Операция **не останавливает ВМки** в облаке, но не даёт редактировать все сущности внутри VDC - params: [] diff --git a/generated/test/resources_yaml/22_vc_nsxt.yaml b/generated/test/resources_yaml/22_vc_nsxt.yaml deleted file mode 100644 index 158f59e..0000000 --- a/generated/test/resources_yaml/22_vc_nsxt.yaml +++ /dev/null @@ -1,139 +0,0 @@ -name: vc_nsxt -service_id: 22 -service_display_name: Сетевой шлюз периметра (Edge) -service_short_name: vc_nsxt -service_man: '# Инструкция по развертыванию Сетевой шлюз периметра (Edge) через платформу

## 1. Общая информация

Сервис **Сетевой шлюз периметра (Edge)** предназначен для создания периметрового сетевого шлюза в рамках одного виртуального датацентра (vDC) или группы виртуальных датацентров (groupvDC).
При создании автоматически разворачивается routed-сеть с адресным пространством `10.10.102.0/24`.
Сервис обеспечивает сетевую изоляцию, маршрутизацию, а также может включать функциональность балансировщика нагрузки AVI (ALB) для последующей интеграции, включая поддержку кластеров Штурвал.

### Доступные операции

**create** — Создание нового Edge с привязкой к vDC или groupvDC и развёртыванием routed-сети.
**delete** — Удаление ранее созданного Edge. Недоступно при наличии зависимых услуг (vApp, VM, Кластер Штурвал).
**modify** — Изменение параметров и сетевых настроек существующего Edge.

---

## 2. Параметры развертывания

Ниже приведены параметры операции **create**.

### Тип родительской услуги
Определяет контекст размещения Edge.
Допустимые значения: `vdc`, `groupvdc`.
Использование:
- При выборе `vdc` обязателен параметр **UUID VDC**.
- При выборе `groupvdc` обязателен параметр **UUID Группы VDC**.

### UUID VDC
Идентификатор виртуального датацентра.
Необходимо предварительно создать vDC через услугу «Виртуальный датацентр (vDC)».
Указывается только при выборе родительского типа `vdc`.

### UUID Группы VDC
Идентификатор группы виртуальных датацентров.
Создаётся через услугу «Группа виртуальных датацентров (groupvDC)».
Используется при выборе родительского типа `groupvdc`.

### Включить ALB
Флаг активации AVI Load Balancer в Cloud Director.
Пример значения: `true`/`false`.
Нужен для развёртывания кластера Штурвал и возможности создания Virtual Services.

### Наименование segroup
Имя сервиса групп (segroup) на уровне ресурсной платформы.
Обязательно при включённом ALB.
Определяет группу, в которой будут выделяться пулы AVI для Virtual Services.

### virtualServicesCount
Количество резервируемых виртуальных сервисов (Virtual Services) на AVI.
Типичное значение: 1–10 в зависимости от нагрузки.

---

## 3. Рекомендованные характеристики

### Тестовое окружение (Test)

- Тип родительской услуги: `vdc`
- virtualServicesCount: 1–2
- ALB: выключен по умолчанию (включать только при необходимости тестирования Штурвала)
- segroup: задаётся только при включённом ALB
- VDC гарантии CPU/RAM: минимальные (поскольку изменить их после создания нельзя)

### Промышленное окружение (Production)

- Тип родительской услуги: `groupvdc` при работе с распределёнными нагрузками или `vdc` для локализованных проектов
- virtualServicesCount: 3–10, исходя из предполагаемого количества публикаций
- ALB: включён, если требуется высокая доступность сервисов или используется кластер Штурвал
- segroup: рекомендуется использовать выделенную группу под проект
- VDC гарантии CPU/RAM: повышенные, с учётом того, что изменить их после создания невозможно без пересоздания vDC

---

## 4. Выходные параметры

### Имя Edge
Уникальное название созданного сетевого шлюза, используется для ссылок и дальнейших операций.

### Имя routed-сети
Автоматически созданная routed-сеть с подсетью `10.10.102.0/24`, используется для подключения ресурсов.

### Параметры Edge
Набор параметров, указанных пользователем при создании: тип услуги, ALB, segroup, virtualServicesCount и др.
Используются в операциях modify и для анализа состояния сервиса.

---

## 5. Дополнительная информация

- В рамках сервиса **один раз при создании задаётся гарантированная доля CPU/RAM vDC**. Изменить её невозможно — требуется пересоздание vDC.
- Удаление Edge недоступно при наличии зависимых ресурсов (vApp, VM, кластер Штурвал).
- При использовании ALB необходимо корректно указывать segroup, чтобы обеспечить корректное выделение пулов AVI.
- При выборе режима `groupvdc` следует учитывать распределение нагрузки между несколькими vDC.
- SNAT для всех ресурсов внутри Edge можно активировать через операцию modify (параметры выделения VIP и ipSpace).

' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 10 - kind: instance - action: create - params: - - id: 8 - code: vdcUid - data_type: string - required: false - ref_svc_id: 21 - descr: UUID Услуги `Виртуальный датацентр (vDC)` - man: 'Необходимо, если выбран тип подключаемой VDC: `vdc`' - sort: 10 - - id: 340 - code: needEnableAVI - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: Включение Load Balancer - man: Параметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указать - sort: 30 - is_modifiable: true - - id: 341 - code: virtualServicesCount - data_type: integer > 0 - required: false - default: "1" - maxvalue: 4 - minvalue: 1 - descr: Кол-во виртуальных сервисов, которые **резервируются** на AVI - man: Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB` - sort: 50 - is_modifiable: true - - id: 621 - code: vdcType - data_type: string - required: true - default: vdc - value_list: - - vdc - - vdcGroup - descr: Тип родительской услуги - man: При выборе vdc обеспечивает сетевую доступность только в рамках этого vdc
При выборе groupvdc обеспечивает сетевую доступность между всеми vdc, которые включены в groupvdc - sort: 0 - - id: 622 - code: vdcGroupUid - data_type: string - required: false - ref_svc_id: 29 - descr: UUID Услуги `Группа виртуальных датацентров (groupvDC)` - man: 'Необходимо, если выбран тип подключаемой VDC: `groupvdc`' - sort: 20 - - id: 825 - code: qosProfile - required: false - descr: Параметр пока не работает
Должен возвращать поле из ресурсной платформы типа vc из .vcd.hardware.gatewayQoSProfiles

Как по идее должен работать.
Нужно заполнить или CFS vdcUid, или vdcGroupUid
Идеально конечно проверять `if (params.vdcType == "vdc" && params.vdcUid != "")` или `if (params.vdcType == "vdcGroup" && params.vdcGroupUid != "")`

Далее надо пойти по стейту vdc -> org -> resPlatform, взять gatewayQoSProfiles
Или пойти по стейту vdcgroup -> vdc -> org -> resPlatform, взять gatewayQoSProfiles

Регулярку могу написать (Виталя) - man: if (vdcUid != '") {
наборфункций1
}

elif (vdcGroupUid != "") {
наборфункций2
}

else {
return "Необходимо выбрать vdc или vdcgroup"
} - sort: 60 - depends_on: vdcUid,vdcGroupUid - is_modifiable: true - - name: delete - id: 25 - kind: instance - action: delete - man: Невозможно удалить если routed-сеть в Edge связана с:
- vApp
- VM
- Kubernetes-кластер Штурвал

Запустить операцию возможно, но будет ошибка - params: [] - - name: modify - id: 111 - kind: instance - action: modify - man: Для создания SNAT Правила убедитесь, что в организации есть свободные IP
Редактировать кол-во свободных IP можно в услуге `Организация в Cloud Director` -> `modify` - params: - - id: 368 - code: needEnableAVI - data_type: boolean - required: false - value_list: - - "false" - - "true" - descr: Включение Load Balancer - man: Параметры `Наименование segroup`, `Кол-во VS на AVI` необходимо также указать - sort: 10 - - id: 369 - code: virtualServicesCount - data_type: integer > 0 - required: false - maxvalue: 4 - minvalue: 1 - descr: Кол-во виртуальных сервисов, которые выделяются на AVI - man: Во избежании коллапса пока выделяется до 4
Необходимо указывать, если включён параметр `Включить ALB` - sort: 30 - - id: 372 - code: ipSpaceName - data_type: string - required: false - descr: Имя ip Space для внешнего IP - man: Необходимо указывать, если включён параметр `Выделить VIP для SNAT` - sort: 50 - - id: 856 - code: qosProfile - data_type: string - required: false - sort: 40 - - name: reconcile - id: 252 - kind: action - action: reconcile - params: [] diff --git a/generated/test/resources_yaml/23_vc_vm.yaml b/generated/test/resources_yaml/23_vc_vm.yaml deleted file mode 100644 index 470873d..0000000 --- a/generated/test/resources_yaml/23_vc_vm.yaml +++ /dev/null @@ -1,153 +0,0 @@ -name: vc_vm -service_id: 23 -service_display_name: VM в Cloud Director (старый формат) (vc_vm) -service_short_name: vc_vm -service_man: Виртуальная машина без каких-либо особенностей.
Данная услуга запускает vc_ip для выдачи белого адреса и подключения к ВМ -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 26 - kind: instance - action: create - params: - - id: 33 - code: vappUid - data_type: uuid - required: true - ref_svc_id: 26 - descr: InstanceUid vApp. vApp должен быть создан - man: InstanceUid vApp. vApp должен быть создан - sort: 10 - - id: 35 - code: vmName - data_type: string - required: true - default: vm0001 - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - descr: Имя ВМ. Не поддерживает спец-символы - man: Имя ВМ. Не поддерживает спец-символы - sort: 20 - - id: 36 - code: vmCpu - data_type: string - required: true - default: "2" - descr: CPU - man: CPU - sort: 30 - is_modifiable: true - - id: 37 - code: vmRam - data_type: string - required: true - default: "2" - descr: RAM (GB) - man: RAM (GB) - sort: 40 - is_modifiable: true - - id: 38 - code: vmDisksize - data_type: string - required: true - default: "10" - descr: Размер диска под сервис (GB) - man: Размер диска под сервис (GB) - sort: 50 - is_modifiable: true - - id: 176 - code: templateName - data_type: string - required: true - default: RockyLinux_9-16G - value_list: - - RockyLinux_9-16G - - OracleLinux_9-16G - - Ubuntu_24-20G - - Ubuntu_22-20G - descr: ОС - man: ОС - sort: 60 - - id: 177 - code: accessIpList - data_type: string - required: true - default: 79.111.119.78/32 185.247.187.1/32 - descr: Вставить содержимое из 'curl ifconfig.io'
IP адреса в CIDR формате через пробел для настройки аксес листов - man: IP адреса в CIDR формате через пробел для настройки аксес листов - sort: 70 - is_modifiable: true - - id: 406 - code: ipSpaceName - data_type: string - required: true - descr: Брать из свойств ресурсной платформы
.vcd.ipSpace

Имя IP-space для выделения внешнего IP (IP выделяется обязательно) - - name: delete - id: 29 - kind: instance - action: delete - params: [] - - name: modify - id: 68 - kind: instance - action: modify - man: Операция автоматически останавливает ВМ. - params: - - id: 186 - code: vmCpu - data_type: integer > 0 - required: false - descr: CPU - man: CPU - sort: 10 - - id: 187 - code: vmRam - data_type: integer > 0 - required: false - descr: RAM - man: RAM - sort: 20 - - id: 188 - code: vmDisksize - data_type: integer > 0 - required: false - descr: Размер диска под сервис (GB) - man: Размер диска под сервис (GB) - sort: 30 - - id: 189 - code: accessIpList - data_type: string - required: false - descr: IP адреса в CIDR формате через пробел для настройки аксес листов - man: IP адреса в CIDR формате через пробел для настройки аксес листов - sort: 40 - - name: resume - id: 28 - kind: instance - action: resume - params: [] - - name: suspend - id: 27 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/25_vcexternalip.yaml b/generated/test/resources_yaml/25_vcexternalip.yaml deleted file mode 100644 index eaa29b4..0000000 --- a/generated/test/resources_yaml/25_vcexternalip.yaml +++ /dev/null @@ -1,162 +0,0 @@ -name: vcexternalip -service_id: 25 -service_display_name: Публичные IP адреса -service_short_name: vcexternalip -service_man: '**Обычно эта услуга разворачивается автоматически при развёртывании более сложных услуг**
Вручную создавать можно, однако услуга требует много параметров, о которых можно просто не знать

Резервировать публичные IP адреса можно только после создания NGcloud Organization, NGcloud Виртуальный датацентр, NGcloud Каталог, Сетевой шлюз периметра.
Вы можете назначить IP адрес для существующего экземпляра сервиса.' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 56 - kind: instance - action: create - params: - - id: 140 - code: serviceUid - data_type: string - required: true - sort: 20 - is_modifiable: true - - id: 141 - code: dnatCreate - data_type: boolean - required: true - default: "true" - descr: Необходимо создать DNAT-правило. - sort: 40 - is_modifiable: true - - id: 142 - code: internalPortAccess - data_type: string - required: true - default: "5432" - descr: Порт для связки ната с адресом. Несколько значений можно передавать через пробел. Если передать all, то dnat будет на все порты. Требует dnatCreate=true
- sort: 60 - is_modifiable: true - - id: 143 - code: snatCreate - data_type: boolean - required: false - descr: Необходимо создать SNAT-правило.
- sort: 50 - is_modifiable: true - - id: 144 - code: internalAddrAccess - data_type: string - required: true - descr: Внутренний адрес для связки ната. Требует dnatCreate=true или snatCreate=true - sort: 70 - is_modifiable: true - - id: 324 - code: fromServiceNamespace - data_type: string - required: true - descr: Namespace составной услуги (для отображения правил FW) - sort: 80 - - id: 325 - code: fromServiceCloudEdgeName - data_type: string - required: false - descr: Edge составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 90 - - id: 326 - code: fromServiceCloudVdcName - required: false - descr: Vdc составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 100 - - id: 327 - code: fromServiceCloudOrgName - data_type: string - required: false - descr: Org составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 110 - - id: 328 - code: fromServiceCloudVmwareUrl - data_type: string - required: false - descr: Api-Url составной услуги (указывать, если resourceRealm связан с CloudDirector) - sort: 120 - - id: 336 - code: ipSpaceName - data_type: string - required: true - descr: Тип ip Space (internet-ipv4-v1 / internet-antiddos-v1 / internet-no-antiddos-v1) - sort: 30 - is_modifiable: true - - id: 488 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 200 - - id: 624 - code: fromServiceCloudEdgeScope - data_type: string - required: false - sort: 130 - - id: 626 - code: fromServiceVdcGroupName - data_type: string - required: false - sort: 140 - - name: delete - id: 57 - kind: instance - action: delete - params: [] - - name: modify - id: 197 - kind: instance - action: modify - params: - - id: 627 - code: serviceUid - data_type: string - required: true - sort: 20 - - id: 628 - code: ipSpaceName - data_type: string - required: true - sort: 30 - - id: 629 - code: dnatCreate - data_type: boolean - required: true - sort: 40 - - id: 630 - code: snatCreate - data_type: boolean - required: true - sort: 50 - - id: 631 - code: internalPortAccess - data_type: string - required: true - sort: 60 - - id: 632 - code: internalAddrAccess - data_type: string - required: true - sort: 70 diff --git a/generated/test/resources_yaml/26_vapp.yaml b/generated/test/resources_yaml/26_vapp.yaml deleted file mode 100644 index c33be31..0000000 --- a/generated/test/resources_yaml/26_vapp.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: vapp -service_id: 26 -service_display_name: Виртуальный каталог ВМ (vApp) -service_short_name: vapp -service_man: '# Инструкция по развертыванию Виртуальный каталог ВМ (vApp) через платформу

## 1. Общая информация

**Виртуальный каталог ВМ (vApp)** — это логическая каталог, объединённая в единый управляемый объект. Сервис предназначен для совместного развертывания, управления жизненным циклом и сетевого взаимодействия набора связанных ВМ. Основные функции включают:
- централизованное управление включением, выключением и приостановкой группы ВМ;
- унифицированный сетевой доступ через привязанный Edge-шлюз;

### Доступные операции

**create** — Создание нового vApp с привязкой к заданным услугам VDC и Edge
**delete** — Удаление существующего vApp. Требуется предварительный перевод vApp в состояние *suspend*. Полное удаление возможно через 14 дней.
**suspend** — Остановка vApp (выключение всех ВМ внутри каталога)
**resume** — Запуск vApp (включение всех ВМ внутри каталога)

---

## 2. Параметры развертывания

Параметры берутся из операции **create**.

### UUID Услуги VDC
Уникальный идентификатор услуги «Виртуальный датацентр (vDC)».
Используется для определения вычислительной инфраструктуры, в которой будет развернут vApp.

### UUID Услуги Edge
Уникальный идентификатор услуги «Сетевой шлюз периметра (Edge)».
Обеспечивает маршрутизацию и сетевое подключение. Может быть привязан к группе VDC, поэтому выбирается отдельно.

### Имя vApp
Строгое имя, соответствующее маске формирования DNS-имени.
Используется как часть в DNS-имени при создании виртуальных машин.

---

## 3. Рекомендованные характеристики
Так как является промежуточным этапом для создания ВМ, все характеристики описываются в услуге `Виртуальная машина`

---

## 4. Выходные параметры

### Параметры vApp
Заданные при создании vApp

---

## 5. Дополнительная информация

- Привязка к VDC и Edge осуществляется раздельно, поскольку один Edge может обслуживать несколько VDC (через услугу `Группа виртуальных датацентров (groupvDC)`). Это гарантирует возможность развернуть ВМ в единой сети, но в разных виртуальных датацентрах.
- Перед удалением vApp необходимо вручную перевести его в состояние **suspend**. Удаление возможно только спустя 14 дней после этого шага.
- Операция delete удаляет весь vApp полностью, включая все виртуальные машины, связанные с ним.
- Рекомендуется заранее планировать сетевые связи и назначения DNS-имён для обеспечения корректной работы сервисов, развернутых внутри vApp.
- При проектировании инфраструктуры следует учитывать зависимости между Edge-шлюзом, VDC и размещаемыми ВМ, чтобы избежать ограничений при масштабировании и интеграции.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 69 - kind: instance - action: create - params: - - id: 190 - code: nsxtUid - data_type: uuid - required: true - ref_svc_id: 22 - descr: UUID Услуги `Сетевой шлюз периметра (Edge)` - man: К какой сети может быть подключен виртуальный каталог - sort: 20 - - id: 191 - code: vappName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$ - minlength: 3 - descr: Уникальное в рамках организации - man: Имеет строгую маску `^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$`

Используется в формировании DNS-Имени (для виртуальных машин) - sort: 30 - - id: 623 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - descr: UUID Услуги `Виртуальный датацентр (vDC)` - man: В каких ресурсах будет создан виртуальный каталог - sort: 10 - - name: delete - id: 70 - kind: instance - action: delete - params: [] - - name: reconcile - id: 285 - kind: action - action: reconcile - params: [] - - name: resume - id: 209 - kind: instance - action: resume - params: [] - - name: suspend - id: 208 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/27_vc_vm_v2.yaml b/generated/test/resources_yaml/27_vc_vm_v2.yaml deleted file mode 100644 index 2b1d235..0000000 --- a/generated/test/resources_yaml/27_vc_vm_v2.yaml +++ /dev/null @@ -1,71 +0,0 @@ -name: vc_vm_v2 -service_id: 27 -service_display_name: VM в Cloud Director (vc_vmV2) -service_short_name: vc_vm_v2 -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 100 - kind: instance - action: create - params: - - id: 301 - code: serverListJson - data_type: json - required: true - default: '[{}]' - maxlength: 65536 - minlength: 10 - descr: Необходимо изменить vappUid и ipSpaceName
Пример конфигурации взять по ссылке ниже

Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2) - sort: 20 - is_modifiable: true - - name: delete - id: 101 - kind: instance - action: delete - params: [] - - name: modify - id: 104 - kind: instance - action: modify - params: - - id: 302 - code: serverListJson - data_type: json - required: true - default: '[{}]' - maxlength: 65536 - minlength: 10 - descr: Объект серверов вида [{}] (Map(Object))
Более подробнее смотреть в README.md (https://gitea.mgmt.nubes.ru/cloudServices/vcVmV2) - sort: 10 - - name: resume - id: 102 - kind: instance - action: resume - params: [] - - name: suspend - id: 103 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/28_vc_vm_v3.yaml b/generated/test/resources_yaml/28_vc_vm_v3.yaml deleted file mode 100644 index f05d808..0000000 --- a/generated/test/resources_yaml/28_vc_vm_v3.yaml +++ /dev/null @@ -1,278 +0,0 @@ -name: vc_vm_v3 -service_id: 28 -service_display_name: Виртуальная машина -service_short_name: vc_vm_v3 -service_man: '# Документация по разворачиванию ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\ложь, определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed" (В нем не будет работать сбор метрик zabbix).

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 132 - kind: instance - action: create - man: '# Документация по использованию услуги развёртывания ВМ в Личном кабинете

Данный сервис позволяет разворачивать виртуальные машины (ВМ) непосредственно из Личного кабинета (ЛК).

## Доступные операции
- **create** — Создание виртуальной машины
- **delete** — Удаление виртуальной машины
- **resume** — Запуск виртуальной машины
- **suspend** — Остановка виртуальной машины

---

## Параметры для развёртывания ВМ

### Обязательные параметры:

**vappUid**
UUID vApp, в которой будет создаваться виртуальная машина.
*Пример: WZ00400*

**vmName**
Уникальное имя виртуальной машины.
*Пример: test-vm*

**vmCpu**
Количество ядер процессора. Должно быть больше 0.
*Пример: 1*

**vmRam**
Объем оперативной памяти в гигабайтах. Должно быть больше 0.
*Пример: 1*


**accessPortList**
Белый список портов для доступа к виртуальной машине извне в формате JSON.
*Пример: ["22","10050]*

**imageVm**
Образ операционной системы для развёртывания.
*Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G*

**userLogin**
Логин пользователя для SSH-доступа.
*По умолчанию: myuser*

**userPublicKey**
Публичный SSH-ключ пользователя в формате OpenSSH.
*Пример: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...*

**needAddZabbixTemplate**
Значение истина\лож определяющее будет ли добавлен хост в zabbix.
*Пример: true*

### Опциональные параметры:

**accessIpList**
Белый список IP-адресов для доступа к виртуальной машине в формате JSON. Если оставить пустым, вм будет доступена со всех адресов.
*Пример: ["192.168.1.1", "10.0.0.5"]*

**vmDisk**
Размер дополнительного диска в гигабайтах. Должно быть больше 0.
*Пример: 50*

**ipSpaceName**
Внешний IP-адрес. Если не требуется — укажите значение "no-needed".

**cloudInit**
YAML-скрипт для кастомизации системы через cloud-init.

---

## Доступные образы операционных систем

### RockyLinux_9-16G-cloudinit
Базовый образ на основе Rocky Linux 9 (Rocky-9.6-x86_64-minimal) для серверных задач.
- Размер системного диска: 16 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Ubuntu_22-20G
Образ на основе Ubuntu Server 22.04 LTS для облачного окружения.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

### Debian_13-20G
Образ на основе Debian 13 (Trixie) для стабильной серверной работы.
- Размер системного диска: 20 ГБ
- Поддержка cloud-init
- Минимальные требования: 1 vCPU, 1 ГБ RAM

---

## Пример использования Cloud-init

```yaml
users:
- name: myuser
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...

packages:
- nginx

runcmd:
- systemctl enable --now nginx
- systemctl restart nginx
```

---

## Результат выполнения

После успешного развёртывания в Личном кабинете появится новая виртуальная машина с заданными характеристиками. SSH-доступ осуществляется с использованием указанных логина и публичного ключа.

---

## Важные примечания

### Особенности работы:
- Для отключения внешнего IP укажите значение "no-needed" в параметре ipSpaceName
- Параметр cloudInit является опциональным

### Ограничения:
- Не рекомендуется использовать продолжительные инструкции в cloud-init (таймаут 5 минут)
- Не поддерживается запись файлов через cloud-init
- Не реализовано создание резервных копий ВМ

---

## Диагностика проблем с cloud-init

### Основной лог-файл:
```bash
/var/log/cloud-init.log
```

### Пакет не устанавливается:
- Проверьте доступность пакета в репозитории
- Убедитесь в правильности написания имени пакета
- Попробуйте установить вручную: `apt install <имя_пакета>` (Debian/Ubuntu) или `dnf install <имя_пакета>` (Rocky Linux)

### Команда не выполняется:
- Проверьте наличие требуемой утилиты в системе
- Убедитесь в правильности синтаксиса команды
- Попробуйте выполнить команду вручную для диагностики' - params: - - id: 407 - code: vappUid - data_type: uuid - required: true - ref_svc_id: 26 - sort: 10 - - id: 408 - code: vmName - data_type: string - required: true - default: web01 - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - sort: 20 - - id: 409 - code: vmCpu - data_type: integer > 0 - required: true - default: "1" - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 30 - is_modifiable: true - - id: 410 - code: vmRam - data_type: integer > 0 - required: true - default: "1" - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 40 - is_modifiable: true - - id: 411 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 50 - is_modifiable: true - - id: 412 - code: ipSpaceName - data_type: string - required: true - sort: 60 - depends_on: vappUid - is_modifiable: true - - id: 413 - code: accessIpList - data_type: json - required: false - regex: ^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$ - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 70 - is_modifiable: true - - id: 414 - code: imageVm - data_type: string - required: true - sort: 90 - depends_on: vappUid - - id: 415 - code: cloudInit - data_type: yaml - required: false - descr: Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. - sort: 200 - - id: 416 - code: userLogin - required: true - default: myuser - descr: Учётка SSH - sort: 180 - - id: 417 - code: userPublicKey - data_type: string - required: true - descr: Публичная часть SSH-Ключа для пользователя - sort: 190 - - id: 448 - code: accessPortList - data_type: string - required: true - default: '["22"]' - descr: 'По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX' - sort: 80 - is_modifiable: true - - name: delete - id: 133 - kind: instance - action: delete - params: [] - - name: modify - id: 159 - kind: instance - action: modify - params: - - id: 493 - code: vmCpu - data_type: integer > 0 - required: false - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 20 - - id: 494 - code: vmRam - data_type: integer > 0 - required: false - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 30 - - id: 495 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 40 - - id: 496 - code: ipSpaceName - data_type: string - required: false - value_list: - - no-needed - - internet-antiddos-v1 - - internet-no-antiddos-v1 - - internet-ipv4-v1 - descr: no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev - sort: 50 - - id: 497 - code: accessIpList - data_type: json - required: false - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 60 - - id: 498 - code: accessPortList - data_type: json - required: false - descr: Формат массива
По каким портам открыть доступ к ВМ.
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX - sort: 70 - - name: reconcile - id: 286 - kind: action - action: reconcile - params: [] - - name: redeploy - id: 164 - kind: action - action: redeploy - params: - - id: 509 - code: vmName - data_type: string - required: true - regex: ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$ - sort: 10 - - id: 510 - code: vmCpu - data_type: integer > 0 - required: true - maxvalue: 64 - minvalue: 1 - descr: шт - sort: 20 - - id: 511 - code: vmRam - data_type: integer > 0 - required: true - maxvalue: 256 - minvalue: 1 - descr: Gb - sort: 30 - - id: 512 - code: vmDisk - data_type: integer > 0 - required: false - regex: ^(?:$|(?:0|[1-9]\d{0,2}|1\d{3}|20(?:[0-3]\d|4[0-8])))$ - descr: Основной диск у vm зависит от образа (см. документацию)
Если необходимо дополнительное место для vm, введите колличество Gb в эту форму - sort: 40 - - id: 513 - code: ipSpaceName - data_type: string - required: false - value_list: - - no-needed - - internet-antiddos-v1 - - internet-no-antiddos-v1 - - internet-ipv4-v1 - descr: no-needed, без внешнего ip
internet-antiddos-v1, с функцией защиты от ddos атак
internet-no-antiddos-v1, с функцией защиты от ddos атак
internet-ipv4-v1 тестовое простанство dev - sort: 50 - - id: 514 - code: accessIpList - data_type: json - required: false - regex: ^(?:$|\[\s*(?:"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?"(?:\s*,\s*"(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,2})?")*)\s*\])$ - descr: Формат массива
Каким адресам будет предоставлен доступ до вм

Требует выделенного внешнего IP
Если ничего не передано, то выставлено ["0.0.0.0/0"] - sort: 60 - - id: 515 - code: imageVm - data_type: string - required: true - value_list: - - RockyLinux_9-16G-cloudinit - - Ubuntu_22-20G - - Debian_13-20G - sort: 80 - - id: 516 - code: userLogin - data_type: string - required: true - descr: Учётка SSH - sort: 180 - - id: 517 - code: userPublicKey - data_type: string - required: true - descr: Публичная часть SSH-Ключа для пользователя - sort: 190 - - id: 518 - code: cloudInit - data_type: yaml - required: false - descr: Можно передать создание дополнительных пользователей.
На текущий момент не реализовано выполнения в cloud-init, установки пакетов, выполнения команд и записи файлов. - sort: 200 - - id: 520 - code: accessPortList - data_type: json - required: false - descr: По каким портам открыть доступ к ВМ.
Порты 22, 10050 проставляются автоматически
Пока доступно:
22 - SSH,
80 - HTTP,
443 - HTTPS,
10050 - ZABBIX - sort: 70 - - name: resume - id: 135 - kind: instance - action: resume - params: [] - - name: suspend - id: 134 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/29_vc_vdc_group.yaml b/generated/test/resources_yaml/29_vc_vdc_group.yaml deleted file mode 100644 index 21afd35..0000000 --- a/generated/test/resources_yaml/29_vc_vdc_group.yaml +++ /dev/null @@ -1,74 +0,0 @@ -name: vc_vdc_group -service_id: 29 -service_display_name: Группа датацентров -service_short_name: vcVdcGroup -service_man: '# Инструкция по развертыванию Группа виртуальных датацентров (groupvDC) через платформу

## 1. Общая информация

Сервис **Группа виртуальных датацентров (groupvDC)** предназначен для логического объединения нескольких виртуальных датацентров (vDC) в единую группу. Это позволяет растягивать SDN между разными vDC и централизованно управлять сетевой связностью. Управление инфраструктурой осуществляется через Cloud Director.
Сервис применяется в случаях, когда требуется обеспечить единое сетевое пространство для распределенных виртуальных датацентров.

### Доступные операции

**create** — Создание новой группы виртуальных датацентров.
**delete** — Удаление существующей группы vDC.
**add_vdc** — Добавление дополнительного виртуального датацентра в группу.
**remove_vdc** — Удаление ранее добавленного виртуального датацентра из группы.

---

## 2. Параметры развертывания

Параметры операции **create**:

### UUID VDC
Идентификатор виртуального датацентра, который будет являться первичным в группе.
Описание: требуется предварительно создать виртуальный датацентр с помощью услуги `Виртуальный датацентр (vDC)`.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Для тестового окружения создавать группу VDC нет необходимости, так как это создаёт дополнительный слой абстракции в Cloud Director

### Промышленное окружение
- Для промышленного окружения, если в тенанте существуют разные VDC, создание groupvdc позволит снизить сетевые издержки (за счёт общей сети)

---

## 4. Выходные параметры

### Параметры groupvdc
Набор параметров, указанных пользователем при создании

---

## 5. Дополнительная информация
- Группа vDC используется для растягивания SDN между несколькими виртуальными датацентрами. Управление всеми сетевыми элементами внутри группы выполняется Cloud Director.
- Удалить первичный vDC (тот, что был указан при операции **create**) невозможно. Для его удаления необходимо удалить всю группу и создать новую.
- Перед добавлением любого vDC в группу он должен быть предварительно развернут через сервис `Виртуальный датацентр (vDC)`.
- Сети создаются не в этой услуге, а в услуге `Сетевой шлюз периметра (Edge)`. В ней необходимо будет выбрать тип `groupvdc`' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: add_vdc - id: 192 - kind: subresource - action: add - subresource: vdc - man: '**Не нужно** выбирать UUID VDC, который уже был добавлен в группу' - params: - - id: 619 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - sort: 10 - - name: create - id: 191 - kind: instance - action: create - man: '**VDC Группа** нужна для объединения всех VDC в организации в одну логическую группу.
Это позволит, к примеру, создать **общую сеть** для всех VDC в организации

- Для создания группы VDC необходимо указать **инстанс** услуги VDC (`Виртуальный датацентр`)
- **Важный момент** - удалить эту VDC из группы нельзя. Если такая потребность появится, необходимо будет **ПОЛНОСТЬЮ** удалить группу VDC и уже потом создать новую' - params: - - id: 618 - code: vdcUid - data_type: uuid - required: true - ref_svc_id: 21 - sort: 10 - - name: delete - id: 195 - kind: instance - action: delete - params: [] - - name: reconcile - id: 251 - kind: action - action: reconcile - params: [] - - name: remove_vdc - id: 193 - kind: subresource - action: remove - subresource: vdc - params: - - id: 620 - code: vdcName - data_type: string - required: true - sort: 10 diff --git a/generated/test/resources_yaml/2_template.yaml b/generated/test/resources_yaml/2_template.yaml deleted file mode 100644 index 601652a..0000000 --- a/generated/test/resources_yaml/2_template.yaml +++ /dev/null @@ -1,81 +0,0 @@ -name: template -service_id: 2 -service_display_name: Темплейт k8s -service_short_name: template -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 74 - kind: instance - action: create - params: - - id: 813 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 814 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 815 - code: accessConfiguration - data_type: map-fixed - required: true - is_modifiable: true - - name: delete - id: 75 - kind: instance - action: delete - params: [] - - name: modify - id: 76 - kind: instance - action: modify - params: - - id: 816 - code: clusterConfiguration - data_type: map-fixed - required: true - - id: 817 - code: accessConfiguration - data_type: map-fixed - required: true - - name: reconcile - id: 298 - kind: action - action: reconcile - params: [] - - name: resume - id: 98 - kind: instance - action: resume - params: [] - - name: suspend - id: 97 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/32_vmpostgre.yaml b/generated/test/resources_yaml/32_vmpostgre.yaml deleted file mode 100644 index f877745..0000000 --- a/generated/test/resources_yaml/32_vmpostgre.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: vmpostgre -service_id: 32 -service_display_name: vc_vm_postgresql_std -service_short_name: vmpostgre -service_man: Сервис настройки PostgreSQL для виртуальной машины.
Требует наличия ВМ -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: [] diff --git a/generated/test/resources_yaml/50_nextcloud.yaml b/generated/test/resources_yaml/50_nextcloud.yaml deleted file mode 100644 index 665cf0b..0000000 --- a/generated/test/resources_yaml/50_nextcloud.yaml +++ /dev/null @@ -1,135 +0,0 @@ -name: nextcloud -service_id: 50 -service_display_name: Nextcloud -service_short_name: nextcloud -service_man: 'Ресурсная платформа: k8s. Автоматизация: helm chart' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 16 - kind: instance - action: create - man: Для установки необходимо:
- ресурсная платформа, где разворачивается Nextcloud, обязана совпадать с ресурсными платформами, где развёрнут Redis и PostgreSQL - params: - - id: 1055 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1056 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 1057 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 1058 - code: appConfiguration - data_type: map-fixed - required: true - sort: 40 - is_modifiable: true - - name: create_backup - id: 404 - kind: subresource - action: create - subresource: backup - man: Перед запуском обязательно надо перевести экземпляр Nextcloud в статус 'suspended' - params: - - id: 1077 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - name: delete - id: 17 - kind: instance - action: delete - man: DEV-Ветка удаления Nextcloud - params: [] - - name: modify - id: 67 - kind: instance - action: modify - params: - - id: 1059 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1060 - code: appConfiguration - data_type: map-fixed - required: true - sort: 20 - - name: reconcile - id: 390 - kind: action - action: reconcile - params: [] - - name: recovery - id: 406 - kind: action - action: recovery - params: - - id: 1078 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1079 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 1080 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 1081 - code: appConfiguration - data_type: map-fixed - required: true - man: Версия Nextcloud будет взята из бэкапа - sort: 40 - - name: restart - id: 66 - kind: action - action: restart - params: [] - - name: resume - id: 129 - kind: instance - action: resume - params: [] - - name: suspend - id: 128 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/81_superset.yaml b/generated/test/resources_yaml/81_superset.yaml deleted file mode 100644 index e935cbe..0000000 --- a/generated/test/resources_yaml/81_superset.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: superset -service_id: 81 -service_display_name: Apache Superset -service_short_name: superset -service_man: 'Apache Superset как сервис.
Ресурсная платформа: k8s.
Автоматизация: k8s operator.
Авторизация: 2FA keycloak (для доменного логина @mgmt.nubes.ru)' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 12 - kind: instance - action: create - man: DEV-Ветка сборки Superset - params: - - id: 14 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 20 - code: emails - data_type: string - required: true - default: testuser1 - descr: Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - man: Учётная запись, которой будут выданы админские права. В формате email [ну не совсем. Для доменных учетных записей - без доменного суффикса]. Обязана находиться в Keycloak. Можно передавать несколько через пробел - sort: 70 - - id: 96 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - man: Квота ядра пода (Указывается в mili). 1000 Mili = 1 ядро - sort: 30 - - id: 97 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 40 - - id: 98 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - - id: 109 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 227 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 60 - - name: delete - id: 13 - kind: instance - action: delete - man: DEV-Ветка удаления Superset - params: [] diff --git a/generated/test/resources_yaml/82_harbor.yaml b/generated/test/resources_yaml/82_harbor.yaml deleted file mode 100644 index 34d03f5..0000000 --- a/generated/test/resources_yaml/82_harbor.yaml +++ /dev/null @@ -1,121 +0,0 @@ -name: harbor -service_id: 82 -service_display_name: Container Registry -service_short_name: harbor -service_man: 'Расширенный реестр для управления Docker-образами с enterprise-функциями безопасности, репликации и контроля доступа.
Container Registry позволяет хранить, развертывать и управлять Docker-образами контейнеров в инфраструктуре NGcloud.
Сервис можно использовать в процессе разработки контейнеров. Например, вы можете настроить систему автоматизации на работу с реестром в Container Registry в рамках процесса непрерывной интеграции. Контейнеры идеально подходят для запуска небольших, независимых и легко изменяемых сервисов.
Чтобы начать работу, создайте реестр и загрузите в него Docker-образ
Авторизация: keycloak' -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 14 - kind: instance - action: create - man: DEV-Ветка сборки Harbor - params: - - id: 16 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 20 - - id: 110 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 30 - - id: 228 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 40 - is_modifiable: true - - id: 229 - code: resourceMemory - data_type: integer > 0 - required: true - default: "200" - maxvalue: 8192 - minvalue: 512 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 50 - is_modifiable: true - - id: 230 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 60 - is_modifiable: true - - id: 231 - code: s3Uid - data_type: uuid - required: true - ref_svc_id: 12 - descr: UUID экземпляра услуги S3 - man: UUID экземпляра услуги S3 - sort: 10 - - name: delete - id: 15 - kind: instance - action: delete - man: DEV-Ветка удаления Harbor - params: [] - - name: modify - id: 270 - kind: instance - action: modify - params: - - id: 822 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - - id: 823 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 500 - - id: 824 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 512 diff --git a/generated/test/resources_yaml/88_k8s_ziti_controller.yaml b/generated/test/resources_yaml/88_k8s_ziti_controller.yaml deleted file mode 100644 index 7270f20..0000000 --- a/generated/test/resources_yaml/88_k8s_ziti_controller.yaml +++ /dev/null @@ -1,90 +0,0 @@ -name: k8s_ziti_controller -service_id: 88 -service_display_name: k8sZitiController -service_short_name: k8sZitiController -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 99 - kind: instance - action: create - params: - - id: 294 - code: resourceCPU - data_type: integer > 0 - required: true - default: "300" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (milicores) - sort: 30 - - id: 295 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (MBytes) - sort: 40 - - id: 296 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - - id: 297 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 60 - - id: 298 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 20 - - id: 299 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - name: delete - id: 105 - kind: instance - action: delete - params: [] diff --git a/generated/test/resources_yaml/89_flask.yaml b/generated/test/resources_yaml/89_flask.yaml deleted file mode 100644 index c1fa5e9..0000000 --- a/generated/test/resources_yaml/89_flask.yaml +++ /dev/null @@ -1,112 +0,0 @@ -name: flask -service_id: 89 -service_display_name: Web-сервер с фреймворком Flask -service_short_name: flask -service_man: '# Инструкция по развертыванию Web-сервер с фреймворком Flask через платформу

## 1. Общая информация

Сервис **Web-сервер с фреймворком Flask** предназначен для развертывания веб-приложений на базе Flask.

### Доступные операции

create — включить сервис, развернуть веб-приложение с указанными параметрами.
delete — удалить сервис, только после suspend.
modify — изменить настройки сервиса и переразвернуть.
suspend — выключить веб-приложение, остановить обслуживание.
resume — включить веб-приложение после suspend.

---

## 2. Параметры развертывания

Параметры входных данных операции **create**:

### Имя домена
Описание: доменное имя для доступа к веб-приложению. Если указан FQDN, происходит проверка DNS на валидность А-записи. А-запись должна указывать на балансировщик ресурсной платформы. Если указано имя в рамках одного октета, оно будет добавлено в публичную DNS-зону.
Пример значения: строка, допустимые FQDN или имя в одном октете. Пример: example.com или myapp.

### Платформа для развертывания
Описание: кластер Kubernetes, в котором будет развернуто приложение.
Пример значения: идентификатор кластера Kubernetes.

### Квота ядра пода
Описание: количество CPU, выделяемое на под, в Milicores.
Пример значения: целое число, например 500 для 0.5 ядра.

### Квота памяти пода
Описание: количество памяти, выделяемое на под, в Megabytes.
Пример значения: целое число, например 512 для 512 MB.

### Кол-во реплик пода
Описание: количество инстансов пода для масштабирования.
Пример значения: целое число, шт, например 2.

### URL Проекта (gitpath)
Описание: полный HTTPS путь до проекта в Git-репозитории.
Пример значения: URL в формате https://github.com/myuser/myproject.git. Доступ к репозиторию должен быть публичным.

### URL HealthCheck
Описание: путь для проверки здоровья приложения внутри пода.
Пример значения: строка, путь, например /api/v1/health.

### Переменные окружения пода
Описание: структура данных, которая будет передана как переменные окружения в под.
Пример значения: ключ-значение, например {"ENV": "production"}.

---

## 3. Рекомендованные характеристики

### Тестовое окружение
- Квота ядра пода: 300m (0.3 ядра)
- Квота памяти пода: 256 MB
- Кол-во реплик пода: 1

### Промышленное окружение
- Квота ядра пода: от 1000m (1 ядро) в зависимости от нагрузки
- Квота памяти пода: от 1024 MB (1 GB) с учетом потребностей приложения
- Кол-во реплик пода: от 2 для обеспечения отказоустойчивости

---

## 4. Выходные параметры
Операция create не возвращает явных выходных параметров. Успешное выполнение операции приводит к развертыванию сервиса, доступного по указанному домену.

---

## 5. Дополнительная информация
- В корне проекта должен находиться файл requirements.txt со списком зависимостей Python.
- Исходный код веб-приложения должен располагаться в директории site.
- Запуск веб-сервера осуществляется командой python app.py.
- Используется версия Python: python:3.12-slim.
- Git-репозиторий должен быть публично доступен для платформы.
- Операция delete возможна только после suspend.
- Операция modify приводит к переразвертыванию с новыми параметрами.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 376 - kind: instance - action: create - params: - - id: 1037 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1038 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 1039 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 1040 - code: appConfiguration - data_type: map-fixed - required: true - sort: 40 - is_modifiable: true - - id: 1041 - code: jsonEnv - data_type: map - required: false - default: '{}' - sort: 50 - is_modifiable: true - - name: delete - id: 379 - kind: instance - action: delete - params: [] - - name: modify - id: 375 - kind: instance - action: modify - params: - - id: 1042 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1043 - code: appConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 1044 - code: jsonEnv - data_type: map - required: false - sort: 30 - - name: reconcile - id: 381 - kind: action - action: reconcile - params: [] - - name: redeploy - id: 380 - kind: action - action: redeploy - params: - - id: 1045 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - name: resume - id: 378 - kind: instance - action: resume - params: [] - - name: suspend - id: 377 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/90_postgres.yaml b/generated/test/resources_yaml/90_postgres.yaml deleted file mode 100644 index 4a5f60e..0000000 --- a/generated/test/resources_yaml/90_postgres.yaml +++ /dev/null @@ -1,250 +0,0 @@ -name: postgres -service_id: 90 -service_display_name: PostgreSQL -service_short_name: postgres -service_man: '# Инструкция по развертыванию PostgreSQL через платформу

---
## 1. Общая информация

PostgreSQL — это надёжная объектно-реляционная СУБД с открытым исходным кодом, поддерживающая расширенный набор функций, транзакции и хранение сложных типов данных. Развёртывание полностью автоматизировано платформой на базе Zalando Postgres Operator с использованием Kubernetes.

## Доступные операции

- **create** — Создание кластера
- **delete** — Удаление кластера
- **modify** — Модификация кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера
- **restart** — Перезапуск кластера
- **recovery** — Восстановление из резервной копии

- **create_user** — Создание пользователя
- **delete_user** — Удаление пользователя

- **create_database** — Создание базы данных
- **delete_database** — Удаление базы данных


---
## 2. Параметры развертывания кластера

Ниже перечислены параметры, которые необходимо указать при создании ресурса PostgreSQL:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество инстансов (реплик) в кластере PostgreSQL. Пример: `2` (master + slave).

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных в гигабайтах. Пример: `20`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`

* **Выделяет внешний IP для доступа к slave:**
Флаг для выделения внешнего IP для slave (реплики чтения). Работает, если slave присутствует в кластере.

* **Имя ipSpace для публикации внешнего IP slave:**
Если включен параметр для slave, то поле необходимо заполнить.

* **UUID экземпляра услуги S3:**
UUID экземпляра S3 для хранения резервных копий.

* **Версия PostgreSQL:**
Версия PostgreSQL для развертывания. Пример: `16`

* **Расписание бэкапов (ext_BACKUP_SCHEDULE):**
Необязательный. Cron-выражение для времени запуска бэкапов. По умолчанию: `0 0 * * *` (ежедневно в полночь).

* **Количество сохраняемых бэкапов (ext_BACKUP_NUM_TO_RETAIN):**
Необязательный. Количество сохраняемых бэкапов. По умолчанию: `7`

* **PgPooler (master / slave):**
Флаги включения PgBouncer для подключений на запись и чтение. При включении создаётся отдельный под.

* **Разрешить подключение без SSL (allowNoSSL):**
По умолчанию подключение с sslmode=require. При `true` разрешается подключение без SSL.

* **Автоскейлинг PV (autoScale):**
Включает автоскейлинг тома. Требует настройки autoScalePercentage, autoScaleTechWindow, autoScaleQuotaGb.

* **Дополнительные параметры PostgreSQL (jsonParameters):**
JSON с переменными конфигурации PostgreSQL. Документация: https://www.postgresql.org/docs/current/runtime-config.html

---
## 3. Выходные параметры

После успешного развертывания ресурса PostgreSQL платформа возвращает ряд параметров.

#### externalConnect

Внешние эндпоинты для подключения к кластеру:
- **master** — для операций записи (host: `write.${namespace}`, port: 5432)
- **slave** — для операций чтения (host: `read.${namespace}`, port: 5432)

Пример ответа платформы:

```json
{
"slave": {
"ip": "",
"fqdn": "",
"uuid": "",
"isExternal": false
},
"master": {
"ip": "<ip>",
"fqdn": "write.<namespace>.<cluster-domain>",
"uuid": "<uuid>",
"isExternal": false
}
}
```

Поля: `ip` — внешний IP; `fqdn` — полное имя хоста; `uuid` — идентификатор; `isExternal` — признак внешнего доступа.

#### internalConnect

Внутренние эндпоинты (FQDN) для подключения из других сервисов внутри той же сети Kubernetes.

Пример ответа платформы:

```json
{
"slave": "",
"master": {
"slave": "",
"master": {
"slave": "",
"master": "postgresqlk8s-master.<namespace>.svc.cluster.local"
}
}
}
```

Для подключения используйте значение `master.master.master` (host для записи) или соответствующее значение slave (host для чтения).

Для подключения используется порт **5432**.

---
## 4. Управление пользователями

### create_user — Создание пользователя

* **Имя пользователя (username):**
Имя создаваемого пользователя. Используется для подключения к базе и настройки прав.
Пример: `myapp_user`

* **Роль (role):**
Тип роли пользователя. Допустимые значения:
- `app_user` — базовые права для DML-операций (SELECT, INSERT, UPDATE, DELETE)
- `ddl_user` — расширенные права: createdb, createrole (управление базами и ролями)

Защищённые имена, которые нельзя использовать: `admin`, `postgres`, `standby`.

### delete_user — Удаление пользователя

* **Имя пользователя (username):**
Имя удаляемого пользователя. Пример: `myapp_user`

Пользователя нельзя удалить, если он является владельцем базы данных. Сначала удалите или передайте владение базами данных другому пользователю.

---
## 5. Управление базами данных

### create_database — Создание базы данных

* **Имя базы данных (dbName):**
Название создаваемой базы данных. Пример: `myapp_db`

* **Владелец базы данных (dbOwner):**
Имя пользователя-владельца базы. Должен существовать в кластере (создан через create_user). Пример: `myapp_user`

### delete_database — Удаление базы данных

* **Имя базы данных (dbName):**
Название удаляемой базы данных. Пример: `myapp_db`
' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 19 - kind: instance - action: create - man: руководство - params: - - id: 788 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 789 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 790 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - is_modifiable: true - - id: 791 - code: postgresConfiguration - data_type: map-fixed - required: true - sort: 40 - is_modifiable: true - - id: 792 - code: postgresConf - data_type: array-map-fixed - required: false - sort: 50 - is_modifiable: true - - id: 793 - code: backupConfiguration - data_type: map-fixed - required: true - sort: 60 - is_modifiable: true - - id: 794 - code: autoscaleConfiguration - data_type: map-fixed - required: true - sort: 70 - is_modifiable: true - - name: create_backup - id: 264 - kind: subresource - action: create - subresource: backup - params: [] - - name: create_database - id: 245 - kind: subresource - action: create - subresource: database - params: - - id: 741 - code: dbName - data_type: string - required: true - regex: ^[A-Za-z0-9]+$ - - id: 742 - code: dbOwner - data_type: string - required: true - - name: create_user - id: 241 - kind: subresource - action: create - subresource: user - params: - - id: 733 - code: username - data_type: string - required: true - regex: ^[A-Za-z0-9]+$ - maxlength: 62 - minlength: 2 - - id: 740 - code: role - data_type: string - required: true - value_list: - - app_user - - ddl_user - descr: Выбрать роль из списка - man: '`app_user` — стандартный пользователь с базовым набором прав
`ddl_user` — пользователь с расширенными правами, включая управление ролями и базами данных' - - name: delete - id: 20 - kind: instance - action: delete - params: - - id: 457 - code: deleteS3Bucket - data_type: boolean - required: true - default: "true" - value_list: - - "false" - - "true" - descr: Также удалить технический S3 Bucket с бэкапами? - sort: 10 - - name: delete_database - id: 246 - kind: subresource - action: delete - subresource: database - params: - - id: 743 - code: dbName - data_type: string - required: true - - name: delete_user - id: 244 - kind: subresource - action: delete - subresource: user - params: - - id: 739 - code: username - data_type: string - required: true - descr: 'Пример: `username-admin`' - - name: modify - id: 48 - kind: instance - action: modify - params: - - id: 795 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 796 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 797 - code: postgresConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 798 - code: postgresConf - data_type: array-map-fixed - required: false - sort: 40 - - id: 799 - code: backupConfiguration - data_type: map-fixed - required: true - sort: 50 - - id: 800 - code: autoscaleConfiguration - data_type: map-fixed - required: true - sort: 60 - - name: reconcile - id: 263 - kind: action - action: reconcile - params: [] - - name: recovery - id: 47 - kind: action - action: recovery - params: - - id: 801 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 802 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 803 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 804 - code: postgresConfiguration - data_type: map-fixed - required: true - sort: 40 - - id: 805 - code: postgresConf - data_type: array-map-fixed - required: false - sort: 50 - - id: 806 - code: backupConfiguration - data_type: map-fixed - required: true - sort: 60 - - id: 807 - code: autoscaleConfiguration - data_type: map-fixed - required: true - sort: 70 - - name: restart - id: 54 - kind: action - action: restart - man: ВНИМАНИЕ - Рестарт предполагает УДАЛЕНИЕ подов.
Может быть полная поломка. Крайне осторожно запускать при работе - params: [] - - name: resume - id: 114 - kind: instance - action: resume - params: [] - - name: suspend - id: 115 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/91_redis.yaml b/generated/test/resources_yaml/91_redis.yaml deleted file mode 100644 index 2efb3d8..0000000 --- a/generated/test/resources_yaml/91_redis.yaml +++ /dev/null @@ -1,85 +0,0 @@ -name: redis -service_id: 91 -service_display_name: Redis -service_short_name: redis -service_man: 'Redis кластер. Под кеши.
Ресурсная платформа: k8s.
Автоматизация: k8s operator
port 6379' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 21 - kind: instance - action: create - params: - - id: 1061 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1062 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 1063 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - is_modifiable: true - - name: delete - id: 22 - kind: instance - action: delete - params: [] - - name: modify - id: 394 - kind: instance - action: modify - params: - - id: 1064 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1065 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 20 - - name: reconcile - id: 391 - kind: action - action: reconcile - params: [] - - name: resume - id: 393 - kind: instance - action: resume - params: [] - - name: suspend - id: 392 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/92_mongodb.yaml b/generated/test/resources_yaml/92_mongodb.yaml deleted file mode 100644 index 067b1bb..0000000 --- a/generated/test/resources_yaml/92_mongodb.yaml +++ /dev/null @@ -1,191 +0,0 @@ -name: mongodb -service_id: 92 -service_display_name: MongoDB -service_short_name: mongodb -service_man: '# Инструкция по развертыванию MongoDB через платформу

## 1. Общая информация

MongoDB — документоориентированная распределённая база данных, обеспечивающая высокую доступность, горизонтальное масштабирование и гибкую модель хранения.

### Доступные операции с кластером

* **create** — создание базы
* **delete** — удаление базы данных
* **suspend** — остановка базы данных
* **resume** — запуск базы данных
* **modify** — изменение базы данных

### Доступные операции с пользователями

* **create_user** — создание пользователя
* **modify_user** — модификация пользователя
* **delete_user** — удаление пользователя

---

## 2. Параметры развертывания базы данных

Эти параметры необходимо указать при создании базы данных.

### Платформа для развертывания

Среда, в которой будет развернут кластер. Выбирается из предложенного списка.

### Количество узлов

Количество реплик в кластере MongoDB.
Оптимально выбирать нечётное значение, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность базы данных даже при отказе одной из нод.

> **Примечание:** уменьшение количества узлов после создания кластера не рекомендуется.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных в гигабайтах.
Пример: `20`

### Имя ipSpace для публикации внешнего IP

Имя ipSpace, через который будет выделен внешний IP для доступа к master-узлу.
Укажите `no-needed`, если внешний адрес не требуется.
Пример: `internet-no-antiddos-v1`

### Список разрешённых IP-адресов

Список IP-адресов или подсетей, с которых разрешён доступ к кластеру.
Если оставить пустым — доступ открыт для всех источников.
Пример: `["10.0.0.0/24", "192.168.1.10/32"]`

---

## 3. Параметры модификации базы данных

Все параметры, которые вы указываете при модификации, являются необязательными — система автоматически подставит ранее сохранённые значения, и при необходимости вы можете изменить их на нужные.

### Количество узлов

Количество реплик в кластере MongoDB.
Оптимально выбирать нечётное значение, так как это обеспечивает корректный процесс выбора ведущего узла и сохраняет работоспособность базы данных даже при отказе одной из нод.

> **Примечание:** уменьшение количества узлов после создания кластера не рекомендуется.

### Квота памяти пода (MB)

Объём памяти для одного пода в мегабайтах.
Пример: `2048`

### Квота CPU пода (mCPU)

CPU-квота для пода в миликорах (1000 mCPU = 1 vCPU).
Пример: `1000`

### Размер диска для базы данных (GB)

Объём диска для хранения данных указывается в гигабайтах. Его можно увеличить при необходимости, однако уменьшить уже выделенный размер невозможно.
Пример: `20`

### Имя ipSpace для публикации внешнего IP

Имя ipSpace, через который будет выделен внешний IP для доступа к master-узлу.
Укажите `no-needed`, если внешний адрес не требуется.
Пример: `internet-no-antiddos-v1`

### Список разрешённых IP-адресов

Список IP-адресов или подсетей, с которых разрешён доступ к кластеру.
Если оставить пустым — доступ открыт для всех источников.
Пример: `["10.0.0.0/24", "192.168.1.10/32"]`

---

## 3. Параметры создания пользователя

### Имя пользователя

Указывается имя пользователя (любой регистр).
Пример: `readApp`

### Имя базы данных

Название базы, в которой будет создан пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read** — доступ только на чтение
* **readWrite** — чтение и изменение данных
* **dbOwner** — полный контроль над базой данных

---

## 4. Параметры модификации пользователя

### Имя пользователя

Необходимо выбрать существующего пользователя.
Если список пуст, требуется предварительно создать пользователя.

### Имя базы данных

База данных, к которой относится пользователь.
Если база отсутствует, она будет создана автоматически.
Пример: `Apps_9392`

### Имя роли

* **read**
* **readWrite**
* **dbOwner**

---

## 5. Параметры удаления пользователя

### Имя пользователя

Выберите пользователя из списка для удаления.

---

## 6. Выходные параметры

После успешного развертывания базы данных платформа возвращает ключевые параметры.

### internalConnect

Внутренний эндпоинт для подключения к кластеру из сервисов, работающих в той же сети.
Используется для внутренних интеграций и системных сервисов.

### externalConnect

Внешний FQDN для подключения к кластеру извне.
Порт подключения — **27017**.

---

## 7. Пример подключения

Перед подключением необходимо установить **mongosh**.

Команда подключения к базе данных:

```
mongosh "mongodb://<username>:<password>@<endpoint_db>:27017/<dbName>"
```

Где:

* `<username>` — имя пользователя
* `<password>` — пароль
* `<endpoint_db>` — internalConnect или externalConnect
* `<dbName>` — имя базы данных

## 8. Дополнительная информация

Сейчас соединение с базой работает без шифрования, и доступ к кластеру осуществляется только по логину и паролю.' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 37 - kind: instance - action: create - params: - - id: 487 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `2`' - sort: 10 - is_modifiable: true - - id: 588 - code: resourceMemory - data_type: integer > 0 - required: true - minvalue: 512 - descr: 'Пример: `2048`' - is_modifiable: true - - id: 589 - code: resourceCPU - data_type: integer > 0 - required: true - descr: 'Пример: `1000`' - is_modifiable: true - - id: 590 - code: resourceDisk - data_type: integer > 0 - required: true - descr: 'Пример: `20`' - is_modifiable: true - - id: 595 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 646 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - depends_on: resourceRealm - is_modifiable: true - - id: 889 - code: masterAccessList - data_type: json - required: true - default: '[]' - descr: Список IP-адресов, с которых разрешён доступ. Если оставить пустым — доступ открыт всем. - man: 'Передаётся как массив строк. Пример: ["192.168.0.0", "192.168.0.1"]' - is_modifiable: true - - name: create_user - id: 198 - kind: subresource - action: create - subresource: user - params: - - id: 635 - code: username - data_type: string - required: true - - id: 636 - code: dbName - data_type: string - required: true - - id: 643 - code: role - data_type: string - required: true - value_list: - - dbOwner - - read - - readWrite - - name: delete - id: 190 - kind: instance - action: delete - params: [] - - name: delete_user - id: 199 - kind: subresource - action: delete - subresource: user - params: - - id: 644 - code: username - data_type: string - required: true - - name: modify - id: 201 - kind: instance - action: modify - params: - - id: 648 - code: resourceInstances - data_type: integer > 0 - required: false - descr: 'Пример: `2`' - - id: 649 - code: resourceMemory - data_type: integer > 0 - required: false - minvalue: 512 - descr: 'Пример: `2048`' - - id: 650 - code: resourceCPU - data_type: integer > 0 - required: false - minvalue: 500 - descr: 'Пример: `1000`' - - id: 651 - code: resourceDisk - data_type: integer > 0 - required: false - descr: 'Пример: `20`' - - id: 653 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`' - - id: 890 - code: masterAccessList - data_type: json - required: false - default: '[]' - descr: Список IP-адресов, с которых разрешён доступ. Если оставить пустым — доступ открыт всем. - man: 'Передаётся как массив строк. Пример: ["192.168.0.0", "192.168.0.1"]' - - name: modify_user - id: 200 - kind: subresource - action: modify - subresource: user - params: - - id: 640 - code: username - data_type: string - required: true - - id: 641 - code: dbName - data_type: string - required: true - - id: 642 - code: role - data_type: string - required: true - value_list: - - dbOwner - - read - - readWrite - - name: resume - id: 196 - kind: instance - action: resume - params: [] - - name: suspend - id: 194 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/93_rabbitmq.yaml b/generated/test/resources_yaml/93_rabbitmq.yaml deleted file mode 100644 index 50da006..0000000 --- a/generated/test/resources_yaml/93_rabbitmq.yaml +++ /dev/null @@ -1,164 +0,0 @@ -name: rabbitmq -service_id: 93 -service_display_name: RabbitMQ -service_short_name: rabbitmq -service_man: '# Инструкция по развертыванию RabbitMQ через платформу

---
## 1. Общая информация
RabbitMQ — это брокер сообщений с открытым исходным кодом, который обеспечивает надёжную доставку сообщений между приложениями.
Позволяет надёжно передавать сообщения между сервисами и системами, интегрироваться с внешними решениями и использовать как внутренние, так и защищённые TLS-подключения. Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание кластера
- **modify** — Изменение параметров кластера
- **delete** — Удаление кластера
- **suspend** — Остановка кластера
- **resume** — Запуск кластера


---
## 2. Параметры развертывания кластера
Ниже перечислены параметры, которые необходимо указать при создании ресурса RabbitMQ:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развернут кластер). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество реплик в кластере RabbitMQ. При значении больше 1 создаётся кластер с репликацией для обеспечения высокой доступности.
Пример: `1` (single node) или `3` (кластер с репликацией)

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `2048`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `1000`

* **Размер (gigabyte) диска для базы данных:**
Размер диска для хранения данных RabbitMQ в гигабайтах. Пример: `50`

* **Выделяет внешний IP для доступа к master:**
Флаг, определяющий, нужно ли выделять внешний IP для доступа к master-узлу. При включении создаётся Service типа LoadBalancer и настраивается VIP на порту 5672.
Пример: `true` или `false`

* **Имя ipSpace для публикации внешнего IP master:**
Если включен предыдущий параметр, то поле необходимо заполнить. Пример: `internet-no-antiddos-v1`


---
## 3. Модификация кластера
Операция **modify** позволяет изменить параметры существующего кластера RabbitMQ.

**Изменяемые параметры:**
* **Квота (megabyte) памяти пода** — можно увеличить или уменьшить
* **Квота (millicore) ядра пода** — можно увеличить или уменьшить
* **Размер (gigabyte) диска для базы данных** — можно только увеличить (уменьшение не поддерживается)
* **Количество узлов в сети** — можно только увеличить (уменьшение не поддерживается)
* **Выделяет внешний IP для доступа к master** — можно включить или выключить
* **Имя ipSpace для публикации внешнего IP master** — можно изменить при включенном внешнем IP

**Ограничения:**
* Уменьшение размера диска не поддерживается
* Уменьшение количества реплик не поддерживается

---
## 4. Выходные параметры
После успешного развертывания ресурса RabbitMQ платформа возвращает ряд параметров в разделе "Поля состояния (сгенерированные значения)":

**clusterDomain**
Домен кластера Kubernetes, в котором развернут RabbitMQ.
Пример: `cluster.local`

**inernalConnect**
Внутренние эндпоинты для подключения к кластеру RabbitMQ из других сервисов, развернутых внутри той же сети.
Содержит:
* **master** — FQDN для подключения к кластеру. Пример: `rabbitmqk8s.{namespace}.svc.{clusterDomain}`

**externalConnect**
Внешние эндпоинты для подключения к кластеру RabbitMQ извне.
Содержит объекты с полями:
* **admin** — доступ к веб-интерфейсу управления:
* `fqdn` — полное доменное имя для веб-интерфейса. Пример: `admin.{namespace}.{domain}`
* `ip` — IP-адрес
* **master** — доступ к AMQP протоколу (если включен внешний IP):
* `fqdn` — полное доменное имя для AMQP. Пример: `write.{namespace}.{domain}`
* `ip` — IP-адрес

**monitoring**
Информация о дашбордах мониторинга:
* **allDashboards** — URL для доступа ко всем дашбордам Grafana

Для подключения используются следующие порты:

* **5672** — AMQP протокол (внутренний и внешний доступ, если включен внешний IP)
* **15672** — веб-интерфейс управления (доступен через Ingress по HTTPS)

**Учётные данные**
Данные для подключения к RabbitMQ доступны в разделе "Учётные данные":
* **adminUser** — имя пользователя администратора
* **adminPass** — пароль администратора


---
## 5. Примеры подключения через консоль (rabbitmqadmin)

### Работа с очередями через rabbitmqadmin

Для работы с RabbitMQ через консоль используется утилита `rabbitmqadmin`. Установите её или используйте образ с предустановленной утилитой.

Задайте переменные окружения с учётными данными:

```bash
export RABBITMQ_USERNAME=<adminUser>
export RABBITMQ_PASSWORD=<adminPass>
export RABBIT_HOST=<host>
```

Где:
* `<adminUser>` и `<adminPass>` — учётные данные из раздела "Учётные данные"
* `<host>` — адрес для подключения:
* Для внешнего подключения: `externalConnect.admin.fqdn` или `externalConnect.master.fqdn`

**Создание очереди:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
declare queue name=healthcheck durable=false
```

**Листинг очередей:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
list queues
```

**Отправка сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
publish exchange=amq.default routing_key=healthcheck payload="ping-$(date +%s)"
```

**Чтение сообщения:**

```bash
rabbitmqadmin \
-H "$RABBIT_HOST" -P 15672 \
-u "$RABBITMQ_USERNAME" -p "$RABBITMQ_PASSWORD" \
get queue=healthcheck ackmode=ack_requeue_false
```

---
## 6. Дополнительная информация
Для подключения к кластеру RabbitMQ используйте полученные эндпоинты из раздела "Поля состояния (сгенерированные значения)" и учётные данные из раздела "Учётные данные".

Веб-интерфейс управления доступен по адресу, указанному в параметре `externalConnect.admin.fqdn` через HTTPS.

Для внутреннего подключения используйте адрес из `inernalConnect.master` на порту 5672.

---' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 38 - kind: instance - action: create - params: - - id: 116 - code: resourceCPU - data_type: integer > 0 - required: true - default: "1000" - maxvalue: 4000 - minvalue: 500 - descr: 'Пример: `2000`' - sort: 20 - is_modifiable: true - - id: 117 - code: resourceMemory - data_type: integer > 0 - required: true - default: "1124" - maxvalue: 8192 - minvalue: 512 - descr: 'Пример: `2048`' - sort: 30 - is_modifiable: true - - id: 118 - code: resourceDisk - data_type: integer > 0 - required: true - default: "30" - maxvalue: 999 - minvalue: 5 - descr: 'Пример: `20`' - sort: 40 - is_modifiable: true - - id: 119 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Выбрать платформу из списка - sort: 10 - - id: 224 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - sort: 50 - is_modifiable: true - - id: 225 - code: needExternalAddressMaster - data_type: boolean - required: true - default: "false" - value_list: - - "false" - - "true" - descr: 'Флаг, определяющий, нужно ли выделять внешний IP для доступа к master. Пример: `true` или `false`' - sort: 60 - is_modifiable: true - - id: 543 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - is_modifiable: true - - name: delete - id: 39 - kind: instance - action: delete - params: [] - - name: modify - id: 106 - kind: instance - action: modify - params: - - id: 304 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 4000 - minvalue: 500 - descr: 'Пример: `2000`' - sort: 10 - - id: 305 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 512 - descr: 'Пример: `2048`' - sort: 20 - - id: 306 - code: resourceDisk - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: 'Пример: `20`' - sort: 10 - - id: 307 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: 'Пример: `1`' - sort: 40 - - id: 308 - code: needExternalAddressMaster - data_type: boolean - required: true - value_list: - - "false" - - "true" - descr: Выделяет внешний (белый) IP для доступа к master - sort: 50 - - id: 545 - code: ipSpaceNameMaster - data_type: string - required: false - descr: 'Пример: `internet-no-antiddos-v1`' - - name: resume - id: 117 - kind: instance - action: resume - params: [] - - name: suspend - id: 116 - kind: instance - action: suspend - man: Пока не работает из за того что RabbitmqCluster нельзя занулить - params: [] diff --git a/generated/test/resources_yaml/94_lucee.yaml b/generated/test/resources_yaml/94_lucee.yaml deleted file mode 100644 index ca0f8bf..0000000 --- a/generated/test/resources_yaml/94_lucee.yaml +++ /dev/null @@ -1,118 +0,0 @@ -name: lucee -service_id: 94 -service_display_name: Lucee -service_short_name: lucee -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 49 - kind: instance - action: create - params: - - id: 1019 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1020 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 1021 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 1022 - code: appConfiguration - data_type: map-fixed - required: true - sort: 40 - is_modifiable: true - - id: 1023 - code: jsonEnv - data_type: map - required: false - default: '{}' - man: Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ - sort: 50 - is_modifiable: true - - name: delete - id: 50 - kind: instance - action: delete - params: [] - - name: modify - id: 55 - kind: instance - action: modify - params: - - id: 1024 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1025 - code: appConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 1026 - code: jsonEnv - data_type: map - required: false - man: Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ - sort: 30 - - name: reconcile - id: 373 - kind: action - action: reconcile - params: [] - - name: redeploy - id: 53 - kind: action - action: redeploy - params: - - id: 1027 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - name: restart - id: 163 - kind: action - action: restart - params: [] - - name: resume - id: 95 - kind: instance - action: resume - params: [] - - name: suspend - id: 96 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/95_nodejs.yaml b/generated/test/resources_yaml/95_nodejs.yaml deleted file mode 100644 index 6ac319c..0000000 --- a/generated/test/resources_yaml/95_nodejs.yaml +++ /dev/null @@ -1,114 +0,0 @@ -name: nodejs -service_id: 95 -service_display_name: NodeJS -service_short_name: nodejs -service_man: Развертывает контейнер в k8s кластере с node, который можно использовать для запуска своих приложений.
Приложение должно быть доступно по ссылки в git репозитории, которая является входным параметром. -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 58 - kind: instance - action: create - params: - - id: 1028 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1029 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 20 - is_modifiable: true - - id: 1030 - code: accessConfiguration - data_type: map-fixed - required: true - sort: 30 - - id: 1031 - code: appConfiguration - data_type: map-fixed - required: true - sort: 40 - is_modifiable: true - - id: 1032 - code: jsonEnv - data_type: map - required: false - default: '{}' - man: Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ - sort: 50 - is_modifiable: true - - name: delete - id: 61 - kind: instance - action: delete - params: [] - - name: modify - id: 59 - kind: instance - action: modify - params: - - id: 1033 - code: clusterConfiguration - data_type: map-fixed - required: true - sort: 10 - - id: 1034 - code: appConfiguration - data_type: map-fixed - required: true - sort: 20 - - id: 1035 - code: jsonEnv - data_type: map - required: false - man: Передаётся в формате КЛЮЧ:ЗНАЧЕНИЕ - sort: 30 - - name: reconcile - id: 374 - kind: action - action: reconcile - params: [] - - name: redeploy - id: 60 - kind: action - action: redeploy - params: - - id: 1036 - code: startupConfiguration - data_type: map-fixed - required: true - sort: 10 - - name: resume - id: 121 - kind: instance - action: resume - params: [] - - name: suspend - id: 120 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/96_pgadmin.yaml b/generated/test/resources_yaml/96_pgadmin.yaml deleted file mode 100644 index 0a3efa3..0000000 --- a/generated/test/resources_yaml/96_pgadmin.yaml +++ /dev/null @@ -1,158 +0,0 @@ -name: pgadmin -service_id: 96 -service_display_name: pgAdmin -service_short_name: pgadmin -service_man: Инструмент с графическим интерфейсом для управления базами данных PostgreSQL -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 62 - kind: instance - action: create - params: - - id: 164 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 165 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (milicores). 1000Mili = 1 Ядро - man: Квота ядра пода (milicores). 1000Mili = 1 Ядро - sort: 30 - is_modifiable: true - - id: 166 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 512 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - sort: 40 - is_modifiable: true - - id: 167 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 50 - is_modifiable: true - - id: 169 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 170 - code: login - data_type: string - required: true - regex: ^([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)$ - maxlength: 255 - minlength: 3 - descr: Логин для подключения к pgAdmin, в формате email (login@email.net) - man: Логин для подключения к pgAdmin, в формате email (login@email.net) - sort: 60 - - id: 171 - code: password - data_type: string - required: true - descr: Пароль для подключения к pgAdmin - man: Пароль для подключения к pgAdmin - sort: 70 - is_sensitive: true - - name: delete - id: 63 - kind: instance - action: delete - params: [] - - name: modify - id: 64 - kind: instance - action: modify - params: - - id: 172 - code: resourceCPU - data_type: integer > 0 - required: false - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - - id: 173 - code: resourceMemory - data_type: integer > 0 - required: false - maxvalue: 8192 - minvalue: 512 - descr: Квота памяти пода (MBytes) - man: Квота памяти пода (MBytes) - - id: 174 - code: resourceDisk - data_type: integer > 0 - required: false - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - - name: redeploy - id: 65 - kind: action - action: redeploy - params: - - id: 277 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - - name: resume - id: 123 - kind: instance - action: resume - params: [] - - name: suspend - id: 122 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/97_nodered.yaml b/generated/test/resources_yaml/97_nodered.yaml deleted file mode 100644 index 4edaed8..0000000 --- a/generated/test/resources_yaml/97_nodered.yaml +++ /dev/null @@ -1,91 +0,0 @@ -name: nodered -service_id: 97 -service_display_name: NodeRed -service_short_name: nodered -lifecycle: - suspend_on_destroy_default: false - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 72 - kind: instance - action: create - params: - - id: 193 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 30 - - id: 194 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - sort: 40 - - id: 195 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 60 - - id: 196 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 197 - code: domain - data_type: string - required: true - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - man: Наименование поддомена, будет добавлено в k8stemplate.dev.nubes.ru - sort: 10 - - id: 323 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - sort: 50 - - name: delete - id: 73 - kind: instance - action: delete - params: [] diff --git a/generated/test/resources_yaml/98_http.yaml b/generated/test/resources_yaml/98_http.yaml deleted file mode 100644 index 8a0c369..0000000 --- a/generated/test/resources_yaml/98_http.yaml +++ /dev/null @@ -1,160 +0,0 @@ -name: http -service_id: 98 -service_display_name: Простой HTTP контейнер -service_short_name: http -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 77 - kind: instance - action: create - params: - - id: 212 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 10 - - id: 213 - code: resourceCPU - data_type: integer > 0 - required: true - default: "100" - maxvalue: 4000 - minvalue: 100 - descr: Квота ядра пода (Указывается в mili) - man: Квота ядра пода (Указывается в mili) - sort: 30 - is_modifiable: true - - id: 214 - code: resourceMemory - data_type: integer > 0 - required: true - default: "200" - maxvalue: 8192 - minvalue: 128 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 40 - is_modifiable: true - - id: 215 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество реплик приложения. Трафик будет распределяться между подами в режиме Round-Robin - sort: 50 - is_modifiable: true - - id: 216 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - man: Наименование кластера Kubernetes для подключения - sort: 20 - - id: 217 - code: registryPath - data_type: string - required: true - default: nexus-sa.tst.nubes.ru/docker-nubes/jolt - descr: Путь до image, который будет установлен как deployment - man: Путь до image, который будет установлен как deployment - sort: 60 - - id: 241 - code: jsonEnv - data_type: map - required: false - man: Массив переменных, будут переданы в env приложения - sort: 70 - - id: 782 - code: ingressAnnotations - data_type: map - required: false - default: '{}' - man: Формат ключ/значение
Поддерживает пока простые аннотации - sort: 80 - - name: delete - id: 78 - kind: instance - action: delete - params: [] - - name: modify - id: 81 - kind: instance - action: modify - params: - - id: 218 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 4000 - minvalue: 100 - - id: 219 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 128 - - id: 220 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - - name: reconcile - id: 403 - kind: action - action: reconcile - params: [] - - name: redeploy - id: 79 - kind: action - action: redeploy - params: - - id: 272 - code: resourceRealm - data_type: string - required: true - func: getAvailableResourceRealms - descr: Платформа для развертывания - sort: 10 - - name: resume - id: 130 - kind: instance - action: resume - params: [] - - name: suspend - id: 131 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/99_gitea.yaml b/generated/test/resources_yaml/99_gitea.yaml deleted file mode 100644 index 7170b8a..0000000 --- a/generated/test/resources_yaml/99_gitea.yaml +++ /dev/null @@ -1,169 +0,0 @@ -name: gitea -service_id: 99 -service_display_name: Gitea -service_short_name: gitea -service_man: '# Инструкция по развертыванию Gitea через платформу

---
## 1. Общая информация
Gitea — это лёгкий, быстрый и самодостаточный сервис хостинга Git-репозиториев с веб-интерфейсом.
Позволяет создавать и управлять репозиториями, организациями, командами, а также настраивать CI/CD через интеграции.
Развёртывание полностью автоматизировано платформой.

## Доступные операции
- **create** — Создание сервиса Gitea
- **delete** — Удаление сервиса Gitea
- **modify** — Модификация сервиса Gitea
- **suspend** — Остановка сервиса Gitea
- **resume** — Запуск сервиса Gitea

---
## 2. Параметры развертывания
Ниже перечислены параметры, которые необходимо указать при создании ресурса Gitea:

* **Платформа для развертывания:**
Платформа для развертывания (среда, в которой будет развёрнут сервис). Пример: `k8s-3.ext.nubes.ru`.

* **Количество узлов в сети:**
Количество реплик подов Gitea. Пример: `1`

* **Квота (megabyte) памяти пода:**
Квота памяти пода в мегабайтах. Пример: `1024`

* **Квота (millicore) ядра пода:**
Квота CPU пода в миликорах (1000 mCPU = 1 vCPU). Пример: `500`

* **Размер (gigabyte) диска для базы данных:**
Размер PVC для хранения репозиториев и данных Gitea в гигабайтах. Пример: `10`

* **FQDN / Домен:**
Доменное имя, по которому будет доступен сервис. Пример: `git.example.com`

* **Инстанс услуги PostgreSQL:**
UUID услуги k8sPgsql, в которой будет создана база данных `gitea` и пользователь `techgitea`.

* **Дополнительные параметры сервера (iniServerParams):**
JSON-объект с дополнительными параметрами секции `[server]` в `app.ini`. Пример:
```json
{"MAX_CONTENT_LENGTH": "524288000"}
```

* **Дополнительные annotations для Ingress (ingressExtraAnnotations):**
JSON-объект с дополнительными annotations для Ingress-контроллера. Пример:
```json
{"nginx.ingress.kubernetes.io/proxy-body-size": "500m"}
```

---
## 3. Особенности подключения и работы с репозиториями

### 3.1. Доступ только по HTTPS
Сервис развёртывается с **rootless-образом** Gitea. SSH-сервер внутри и он **доступен только внутри кластера Kubernetes**.

**Внешний доступ к репозиториям осуществляется исключительно по HTTPS через Ingress.**

```bash
# Пример клонирования
https://<домен>/<пользователь>/<репозиторий>.git
```

### 3.2. Настройка git для передачи логина и пароля
Для работы с приватными репозиториями через HTTPS необходимо передать учётные данные. Рекомендуется использовать один из следующих способов:

**Встроить креды в URL remote**
```bash
git remote set-url origin https://<логин>:<пароль>@<домен>/<пользователь>/<репозиторий>.git
```
> **Важно:** Логин и пароль администратора создаются автоматически при развертывании и хранятся в Vault.

### 3.3. Работа с большими файлами
По умолчанию `MAX_CONTENT_LENGTH` установлен в **500 МБ**, а Ingress пропускает pack-файлы до **500 МБ**.

Если необходимо запушить файлы близкие к лимиту, увеличьте HTTP-буфер git на стороне клиента:
```bash
git config http.postBuffer 524288000
```

Для файлов **более 500 МБ** рекомендуется использовать **Git LFS**.

---
## 4. Выходные параметры
После успешного развертывания ресурса Gitea платформа возвращает ряд параметров.

Ключевым из них является:

**connectionUrl**
Это внешний URL для доступа к веб-интерфейсу и Git-репозиториям по HTTPS. Пример:
```
https://git.example.com
```

**internalConnect**
Внутренний эндпоинт для подключения к PostgreSQL из других сервисов внутри кластера.

---
## 5. Дополнительная информация
- База данных `gitea` и пользователь `techgitea` создаются автоматически в указанной услуге PostgreSQL.
- DNS-запись и TLS-сертификат (Let''s Encrypt) настраиваются автоматически на основе указанного домена.
- Для изменения параметров сервера Gitea (`app.ini`) используйте операцию **modify** с полем `iniServerParams`.
- Для добавления дополнительных Ingress-annotations используйте операцию **modify** с полем `ingressExtraAnnotations`.
---' -lifecycle: - suspend_on_destroy_default: true - adopt_existing_on_create_default: false -outputs: - params: - - code: state_params - type: map - - code: state_out - type: map - - code: state_params_flat - type: map - - code: state_out_flat - type: map - - code: vault_secrets - type: map - sensitive: true - - code: vault_url - type: string - - code: vault_user_path - type: string - - code: vault_fields - type: list -operations: - - name: create - id: 82 - kind: instance - action: create - params: - - id: 232 - code: resourceCPU - data_type: integer > 0 - required: true - default: "500" - maxvalue: 4000 - minvalue: 300 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - man: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 40 - is_modifiable: true - - id: 233 - code: resourceMemory - data_type: integer > 0 - required: true - default: "512" - maxvalue: 8192 - minvalue: 256 - descr: Квота памяти пода (Указывается в Megabytes) - man: Квота памяти пода (Указывается в Megabytes) - sort: 50 - is_modifiable: true - - id: 234 - code: resourceDisk - data_type: integer > 0 - required: true - default: "1" - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 60 - is_modifiable: true - - id: 235 - code: resourceInstances - data_type: integer > 0 - required: true - default: "1" - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 70 - is_modifiable: true - - id: 237 - code: domain - data_type: string - required: true - default: web01 - regex: ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$ - unique_scope: provider - descr: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - man: Если будет указан FQDN, то происходят проверки DNS на валидность А-записи, или будет добавлено в зону resourceRealm - sort: 20 - - id: 238 - code: psqlUid - data_type: uuid - required: true - ref_svc_id: 90 - descr: UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - man: UUID Услуги k8sPgsql. Пользователя techGitea, базу данных gitea создаёт автоматически - sort: 10 - - id: 818 - code: ingressExtraAnnotations - data_type: map - required: false - is_modifiable: true - - id: 821 - code: iniServerParams - data_type: map - required: false - is_modifiable: true - - name: delete - id: 83 - kind: instance - action: delete - params: [] - - name: modify - id: 91 - kind: instance - action: modify - params: - - id: 259 - code: resourceCPU - data_type: integer > 0 - required: true - maxvalue: 4000 - minvalue: 500 - descr: Квота ядра пода (Указывается в mili). 1000Mili = 1 Ядро - sort: 10 - - id: 260 - code: resourceMemory - data_type: integer > 0 - required: true - maxvalue: 8192 - minvalue: 256 - descr: Квота памяти пода (Указывается в Megabytes) - sort: 20 - - id: 261 - code: resourceDisk - data_type: integer > 0 - required: true - maxvalue: 999 - minvalue: 1 - descr: Квота диска (Указывается в GIGAbytes) - man: Квота диска (Указывается в GIGAbytes) - sort: 30 - - id: 262 - code: resourceInstances - data_type: integer > 0 - required: true - maxvalue: 7 - minvalue: 1 - descr: Количество узлов - man: Количество узлов в сети - sort: 40 - - id: 819 - code: ingressExtraAnnotations - data_type: map - required: false - man: 'Примеры:
- `nginx.ingress.kubernetes.io/proxy-body-size: 500m` (Размер пакета)
- `nginx.ingress.kubernetes.io/proxy-read-timeout: "600"` (Время ожидания при чтении)
- `nginx.ingress.kubernetes.io/proxy-send-timeout: "600"` (Время ожидания отправке)' - - id: 820 - code: iniServerParams - data_type: map - required: false - man: 'Примеры:
- `MAX_CONTENT_LENGTH: 524288000(~500мб)` (Размер пакета в байтах)' - - name: resume - id: 127 - kind: instance - action: resume - params: [] - - name: suspend - id: 126 - kind: instance - action: suspend - params: [] diff --git a/generated/test/resources_yaml/embed.go b/generated/test/resources_yaml/embed.go deleted file mode 100644 index 72e3ff2..0000000 --- a/generated/test/resources_yaml/embed.go +++ /dev/null @@ -1,8 +0,0 @@ -package resources_yaml - -import "embed" - -// Files embeds unified service YAML specs for provider runtime lookup. -// -//go:embed *.yaml -var Files embed.FS diff --git a/generated/test/show_inventory.py b/generated/test/show_inventory.py deleted file mode 100644 index f9508e4..0000000 --- a/generated/test/show_inventory.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python3 -import json, glob - -for f in sorted(glob.glob("/home/naeel/terra/terraform/devops/profiles/test/generated/output_inventory/svc_*.json")): - d = json.load(open(f)) - params = d.get("params", {}) - out = d.get("out", {}) - if params or out: - print(f.split("/")[-1], "params:", list(params.keys()), "out:", list(out.keys())) - if "domain" in params: - print(f" DOMAIN={params['domain']}") diff --git a/generated/test/tmp/.gitkeep b/generated/test/tmp/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/provider/main.go b/provider/main.go index e81043c..56854cb 100644 --- a/provider/main.go +++ b/provider/main.go @@ -17,7 +17,7 @@ import ( ) var ( - version string = "5.0.60" + version string = "5.0.61" ) func main() {